<?php

namespace app\api\controller;

use app\common\controller\Api;
use app\api\controller\send;
use mysql_xdevapi\DocResult;
use think\exception\Handle;
use think\Request;
use think\Response;
use think\exception\HttpResponseException;
use think\Db;
use think\Date;


//1、GET（SELECT）：从服务器取出资源（一项或多项）
//2、POST（CREATE）：在服务器新建一个资源
//3、PUT（UPDATE）：在服务器更新资源（客户端提供完整资源数据）
//4、PATCH（UPDATE）：在服务器更新资源（客户端提供需要修改的资源数据）
//5、DELETE（DELETE）：从服务器删除资源
//测试网站：http://test4.megowx.com/rhc/#/monitor

class V2 extends Api
{
    // 无需登录的接口,*表示全部
    protected $noNeedLogin = ['*'];
    // 无需鉴权的接口,*表示全部
    protected $noNeedRight = ['*'];

    // 数据库的配置
    // protected $databaseInfo = 'mysql://backend:backend1234@47.103.82.136:3306/zh_platform#utf8';
    protected $databaseInfo = '';
    // 接收参数
    protected $decodedata = null;

    // 坐标转换
    protected $x_PI = 52.35987755982988;         // π * 3000.0 / 180.0  这里π = 3.14159265358979324
    protected $PI   = 3.1415926535897932384626;  // π
    protected $a    = 6378245.0;                 // WGS长轴半径
    protected $ee   = 0.00669342162296594323;    // WGS偏心率的平方
    
    // 测试地址
    // http://test6.megowx.com/api/v2/list_device

    public function _initialize()
    {
        parent::_initialize();
        $data = file_get_contents("php://input");    // type: string
        $this->decodedata = json_decode($data, true);

        // 读取文件
        // 从文件中读取数据到PHP变量 
        $json_string = file_get_contents('data.json');        
        // 用参数true把JSON字符串强制转成PHP数组 
        $this->databaseInfo = json_decode($json_string, true);
        if (isset($this->databaseInfo['ip']))
        {
            if(!is_string($this->databaseInfo['ip']))
            {
                $this->error2('The parameter ip of data.json is error', 400);
                die();
            }
        }
        else
        {
            $this->error2('The parameter ip of data.json is missing', 400);
            die();
        }

        if (isset($this->databaseInfo['port']))
        {
            if(!is_integer($this->databaseInfo['port']))
            {
                $this->error2('The parameter port of data.json is error', 400);
                die();
            }
        }
        else
        {
            $this->error2('The parameter port of data.json is missing', 400);
            die();
        }

        if (isset($this->databaseInfo['scheme']))
        {
            if(!is_string($this->databaseInfo['scheme']))
            {
                $this->error2('The parameter scheme of data.json is error', 400);
                die();
            }
        }
        else
        {
            $this->error2('The parameter scheme of data.json is missing', 400);
            die();
        }

        if (isset($this->databaseInfo['username']))
        {
            if(!is_string($this->databaseInfo['username']))
            {
                $this->error2('The parameter username of data.json is error', 400);
                die();
            }
        }
        else
        {
            $this->error2('The parameter username of data.json is missing', 400);
            die();
        }

        if (isset($this->databaseInfo['password']))
        {
            if(!is_string($this->databaseInfo['password']))
            {
                $this->error2('The parameter password of data.json is error', 400);
                die();
            }
        }
        else
        {
            $this->error2('The parameter password of data.json is missing', 400);
            die();
        }
        // protected $databaseInfo = 'mysql://backend:backend1234@47.103.82.136:3306/zh_platform#utf8';
        $this->databaseInfo = "mysql://{$this->databaseInfo['username']}:{$this->databaseInfo['password']}@{$this->databaseInfo['ip']}:{$this->databaseInfo['port']}/{$this->databaseInfo['scheme']}#utf8";

        // 异常处理
        error_reporting(E_ALL);
        set_error_handler([__CLASS__, 'customError']);
        set_exception_handler([__CLASS__, 'customError']);
    }

    /**
     * 设置一个顶级异常处理器
     */
    function customError($errno, $errstr)
    {
        $this->error2('Bad exception', 400);
        die();
    }

    /**
     * 格式化数组内容
     */
    function FormatDataArray($data)
    {
        if (empty($data))
            return $data;
        if (is_array($data)) {
            foreach ($data as $k => &$v) {
                if ($v === null || $v === "") {
                    unset($data[$k]);
                    continue;
                }
                if (is_array($v)) {
                    for ($i = 0; $i < count($v); $i++) {
                        if(!empty($v[$i]))
                        {
                            foreach ($v[$i] as $k1 => &$v1) {
                                if ($v1 === null || $v1 === "") {
                                    unset($v[$i][$k1]);
                                    continue;
                                }
                            }
                        }
                        else
                        {
                            unset($v[$i]);
                        }
                    }
                }
            }
        }
        return $data;
    }

    // http://mg.acciot.com.tw:8000/api/Mixlocationplatform/test
    // http://localhost:9100/api/v2/test?md5=
    //http://rhc.test/api/v2/test
    public function test()
    {
        // echo $this->databaseInfo['ip'];
        // echo $this->databaseInfo['username'];
        // echo $this->databaseInfo['password'];
        // echo $this->databaseInfo['scheme'];
        // echo $this->databaseInfo['port']; 
        // $sql = "SELECT ID,Source,Name,Rule,Valid,Type,State,StartTime,EndTime,PtNum,PtType,Height,RecordTime,Points FROM fence";
        // $list = Db::connect($this->databaseInfo)->query($sql);
        // echo sizeof($list);
        // $data["total"] = 0;
        // $data["result"] = $list;
        // $this->success2($data);
        return;
    }

    private function success2($result, $NeedFormat=true)
    {
        // 插入到logue表中
        $url = $this->GetCurUrl();
        if ($this->decodedata != null) {
            $this->InsertLogue($url, json_encode($this->decodedata), 200, $result);
        }
        if($NeedFormat)
            $result = $this->FormatDataArray($result);

        $response = Response::create($result, 'json', 200)->header([]);
        throw new HttpResponseException($response);
    }

    private function error2($msg, $errcode)
    {
        // 插入到logue表中
        $url = $this->GetCurUrl();
        $msgnew = json_encode($msg);
        if ($this->decodedata != null) {
            $this->InsertLogue($url, json_encode($this->decodedata), $errcode, $msgnew);
        }
        $result["ErrMsg"] = $msg;
        $response = Response::create($result, 'json', $errcode)->header([]);
        throw new HttpResponseException($response);
    }

    // 插入logue日志表
    function InsertLogue($URL, $Request, $HTTPCode, $Response)
    {
        try
        {
            $ID = $this->create_guid();
            if(!is_string($Request))
            {
                return;
            }
            if(!is_string($Response))
            {
                return;
            }
            $Response = str_replace("\"\"", "", $Response);
            $Response = str_replace("'", " ", $Response);
            $sql = "INSERT INTO logue(`ID`,`Type`,`URL`,`Request`,`HTTPCode`,`Response`,createtime) ";
            $sql .= " VALUES('{$ID}', 2,'{$URL}','{$Request}',{$HTTPCode},'{$Response}','" . date('Y-m-d H:i:s') . "')";
            $list = Db::connect($this->databaseInfo)->query($sql);
        }
        catch (Exception $e) 
        {
            die();
        }
    }

    // 判断经纬度是否在中国内 中国的纬度范围是北纬4°~53°。 中国的经度范围是东经73°~135°
    private function isChinaLonLat($lon, $lat)
    {
        if(!is_float($lon) || !is_float($lat))
            return false;
        if($lon < 72.004 || $lon > 137.8347)
            return false;
        if($lat < 0.8293 || $lat > 55.8271)
            return false;
        return true;
    }
    // 坐标转换
        /**
     * WGS84转GCj02(北斗转高德)
     * @param int|string $lng   经度
     * @param int|string $lat   纬度
     * @return array
     */
    function beiDouToAMap($lng = 0, $lat = 0)
    {
        if (!$this->isChinaLonLat($lng, $lat)) {
            return array($lng, $lat);
        } else {
            $dlat      = $this->transFormLat($lng - 105.0, $lat - 35.0);
            $dlng      = $this->transFormLng($lng - 105.0, $lat - 35.0);
            $radlat    = $lat / 180.0 * $this->PI;
            $magic     = sin($radlat);
            $magic     = 1 - $this->ee * $magic * $magic;
            $sqrtmagic = sqrt($magic);
            $dlat      = ($dlat * 180.0) / (($this->a * (1 - $this->ee)) / ($magic * $sqrtmagic) * $this->PI);
            $dlng      = ($dlng * 180.0) / ($this->a / $sqrtmagic * cos($radlat) * $this->PI);
            $mglat     = $lat + $dlat;
            $mglng     = $lng + $dlng;
            return [$mglng, $mglat, 'lng' => $mglng, 'lat' => $mglat];
        }
    }
    /**
     * GCJ02 转换为 WGS84 (高德转北斗)
     * @param int|string $lng   经度
     * @param int|string $lat   纬度
     * @return array
     */
    function aMapToBeiDou($lng = 0, $lat = 0)
    {
        if (!$this->isChinaLonLat($lng, $lat)) {
            return array($lng, $lat);
        } else {
            $dlat      = $this->transFormLat($lng - 105.0, $lat - 35.0);
            $dlng      = $this->transFormLng($lng - 105.0, $lat - 35.0);
            $radlat    = $lat / 180.0 * $this->PI;
            $magic     = sin($radlat);
            $magic     = 1 - $this->ee * $magic * $magic;
            $sqrtmagic = sqrt($magic);
            $dlat      = ($dlat * 180.0) / (($this->a * (1 - $this->ee)) / ($magic * $sqrtmagic) * $this->PI);
            $dlng      = ($dlng * 180.0) / ($this->a / $sqrtmagic * cos($radlat) * $this->PI);
            $mglat     = $lat + $dlat;
            $mglng     = $lng + $dlng;
            return array($lng * 2 - $mglng, $lat * 2 - $mglat);
        }
    }
    /**
     * 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换 百度转高德
     * 即 百度 转 谷歌、高德
     * @param string $bd_lon    百度经度
     * @param string $bd_lat    百度纬度
     * @return array
     */
    function baiDuToAMap($bd_lon = '', $bd_lat = '')
    {
        $x      = $bd_lon - 0.0065;
        $y      = $bd_lat - 0.006;
        $z      = sqrt($x * $x + $y * $y) - 0.00002 * sin($y * $this->x_PI);
        $theta  = atan2($y, $x) - 0.000003 * cos($x * $this->x_PI);
        $gg_lng = $z * cos($theta);
        $gg_lat = $z * sin($theta);
        return array($gg_lng, $gg_lat);
    }
    /**
     * GCJ-02 转换为 BD-09  （火星坐标系转百度 即谷歌、高德转百度）
     * @param string $lng   经度
     * @param string $lat   纬度
     * @return array
     */
    function aMapToBaiDu($lng = '', $lat = '')
    {
        $z      = sqrt($lng * $lng + $lat * $lat) + 0.00002 * sin($lat * $this->x_PI);
        $theta  = atan2($lat, $lng) + 0.000003 * cos($lng * $this->x_PI);
        $bd_lng = $z * cos($theta) + 0.0065;
        $bd_lat = $z * sin($theta) + 0.006;
        return array($bd_lng, $bd_lat);
    }
    private function transFormLat($lng = '', $lat = '')
    {
        $ret  = -100.0 + 2.0 * $lng + 3.0 * $lat + 0.2 * $lat * $lat + 0.1 * $lng * $lat + 0.2 * sqrt(abs($lng));
        $ret += (20.0 * sin(6.0 * $lng * $this->PI) + 20.0 * sin(2.0 * $lng * $this->PI)) * 2.0 / 3.0;
        $ret += (20.0 * sin($lat * $this->PI) + 40.0 * sin($lat / 3.0 * $this->PI)) * 2.0 / 3.0;
        $ret += (160.0 * sin($lat / 12.0 * $this->PI) + 320 * sin($lat * $this->PI / 30.0)) * 2.0 / 3.0;
        return $ret;
    }
    private function transFormLng($lng = 0, $lat = 0)
    {
        $ret  = 300.0 + $lng + 2.0 * $lat + 0.1 * $lng * $lng + 0.1 * $lng * $lat + 0.1 * sqrt(abs($lng));
        $ret += (20.0 * sin(6.0 * $lng * $this->PI) + 20.0 * sin(2.0 * $lng * $this->PI)) * 2.0 / 3.0;
        $ret += (20.0 * sin($lng * $this->PI) + 40.0 * sin($lng / 3.0 * $this->PI)) * 2.0 / 3.0;
        $ret += (150.0 * sin($lng / 12.0 * $this->PI) + 300.0 * sin($lng / 30.0 * $this->PI)) * 2.0 / 3.0;
        return $ret;
    }

    // 判断是不是日期格式: Y-m-d
    private function isDateTime($dateTime)
    {
        return date('Y-m-d', strtotime($dateTime)) == $dateTime;
    }

    //生成唯一用户标识id，长度36位，带"-"
    function create_guid()
    {
        $charid = strtolower(md5(uniqid(mt_rand(), true)));
        $hyphen = chr(45);// "-"
        $uuid = substr($charid, 0, 8) . $hyphen
            . substr($charid, 8, 4) . $hyphen
            . substr($charid, 12, 4) . $hyphen
            . substr($charid, 16, 4) . $hyphen
            . substr($charid, 20, 12);
        return $uuid;
    }

    // php 获取当前访问的完整url
    function GetCurUrl()
    {
        $url = 'http://';
        if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
            $url = 'https://';
        }

        // 判断端口
        if ($_SERVER['SERVER_PORT'] != '80') {
            $url .= $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'] . ':' . $_SERVER['REQUEST_URI'];
        } else {
            $url .= $_SERVER['SERVER_NAME'] . ':' . $_SERVER['REQUEST_URI'];
        }

        return $url;
    }

    // 以下是第2章 获取基础定义接口API
    // 2.1 获取设备类型定义接口
    // http://mg.acciot.com.tw/api/V2/list_device_type
    // http://localhost:9100/api/v2/list_device_type
    //http://rhc.test/api/v2/list_device_type
    public function list_device_type()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'POST') {
            $sql = "SELECT * FROM device_type order by Type asc";

            // 查询数据库表 表: device_type
            $list = Db::connect($this->databaseInfo)->query($sql);

            $data = [];
            $data["total"] = sizeof($list); //返回设备的个数
            $data["result"] = $list;

            $this->success2($data);
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 2.2 获取设备状态定义接口
    // http://mg.acciot.com.tw/api/V2/list_device_state
    // http://localhost:9100/api/v2/list_device_state
    //http://rhc.test/api/v2/list_device_state
    public function list_device_state()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'POST') {
            $sql = "SELECT a.`ID`,b.`Name`,a.`State` FROM device a INNER JOIN device_state b ON a.`State` = b.`State`";

            // 查询数据库表 表: device_type
            $list = Db::connect($this->databaseInfo)->query($sql);

            $data = [];
            $data["total"] = sizeof($list); //返回设备的个数
            $data["result"] = $list;

            $this->success2($data);
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 2.3 获取告警类型定义接口
    // http://mg.acciot.com.tw/api/V2/list_warning_type
    // http://localhost:9100/api/v2/list_warning_type
    //http://rhc.test/api/v2/list_warning_type
    public function list_warning_type()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'POST') {
            $sql = "SELECT * FROM warning_type ORDER BY `Type`";
            // 查询数据库表 表: device_type
            $list = Db::connect($this->databaseInfo)->query($sql);

            $data = [];
            $data["total"] = sizeof($list); //返回设备的个数
            $data["result"] = $list;

            $this->success2($data);
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 2.4 获取人员角色定义接口
    // http://mg.acciot.com.tw/api/V2/list_person_role
    // http://localhost:9100/api/v2/list_person_role
    //http://rhc.test/api/v2/list_person_role
    public function list_person_role()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'POST') {
            $sql = "SELECT * FROM person_role ORDER BY `Role`";
            // 查询数据库表 表: device_type
            $list = Db::connect($this->databaseInfo)->query($sql);

            $data = [];
            $data["total"] = sizeof($list); //返回设备的个数
            $data["result"] = $list;

            $this->success2($data);
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 2.5 获取轮廓类型定义接口
    // http://mg.acciot.com.tw/api/V2/list_outline_type
    // http://localhost:9100/api/v2/list_outline_type
    //http://rhc.test/api/v2/list_outline_type
    public function list_outline_type()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'POST') {
            $sql = "SELECT * FROM outline_type ORDER BY `Type`";

            // 查询数据库表 表: device_type
            $list = Db::connect($this->databaseInfo)->query($sql);

            $data = [];
            $data["total"] = sizeof($list); //返回设备的个数
            $data["result"] = $list;

            $this->success2($data);
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 以下是第3章 人员管理接口API
    // 3.1 添加人员接口
    // http://mg.acciot.com.tw/api/V2/add_person
    // http://localhost:9100/api/v2/add_person
    //http://rhc.test/api/v2/add_person
    public function add_person()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'POST') {
            $Name = "";
            if (isset($this->decodedata['Name'])) {
                $Name = $this->decodedata['Name'];
            }
            if($Name == "")
            {
                $this->error2("The parameter Name cannot be null!", 400);
            }
            else if(!is_string($Name)){
                $this->error2("The parameter Name must be a string!", 400);
            }
            // Gender=1
            $Gender = 1;
            if (isset($this->decodedata['Gender'])) {
                $Gender = $this->decodedata['Gender'];
            }
            if($Gender != 1 && !is_bool($Gender))
            {
                $this->error2("The parameter Gender should be a bool!", 400);
            }
            if($Gender != 1)
                $Gender = 0;
            // Birthday
            $Birthday = "";
            if (isset($this->decodedata['Birthday'])) {
                $Birthday = $this->decodedata['Birthday'];
            }
            if ($Birthday != "")
            {
                if(!is_string($Birthday))
                    $this->error2("The parameter Birthday must be a string!", 400);

                if(!$this->isDateTime($Birthday))
                    $this->error2("Birthday format error!", 400);
            }
            // CardNo
            $CardNo = "";
            if (isset($this->decodedata['CardNo'])) {
                $CardNo = trim($this->decodedata['CardNo']);
            }
            if ($CardNo != "") {
                if(!is_string($CardNo))
                    $this->error2("The parameter CardNo must be a string!", 400);

                $len = strlen($CardNo);
                if ($len != 15 || $len != 18)
                    $this->error2("The length of the CardNo is not correct, should be 15 or 18.", 400);
            }
            // Phone
            $Phone = "";
            if (isset($this->decodedata['Phone'])) {
                $Phone = $this->decodedata['Phone'];
            }
            if ($Phone != "" && !is_string($Phone))
            {
                $this->error2("The parameter Phone must be a string!", 400);
            }
            // Role
            // 数据库连接
            $connect=mysqli_connect($this->decodedata['ip'],$this->decodedata['username'],$this->databaseInfo['password'],$this->decodedata['scheme']);
            if (mysqli_connect_errno($connect))
            {
                $this->error2('Connect MySQL Fail, ' . mysqli_connect_error(), 400);
            }
            $Role = 0;
            if (isset($this->decodedata['Role'])) {
                $Role = $this->decodedata['Role'];

                if(!is_integer($Role))
                    $this->error2("The parameter Role must be a interger!", 400);

                $sql = "SELECT `ID` FROM person_role WHERE `Role` = " . $Role;
                $result = mysqli_query($connect, $sql);
                if(mysqli_num_rows($result) <= 0)
                {
                    // Role值不对
                    $this->error2("The parameter role doesn't exist.", 400);
                }
            }

            // 生成32位GUID，作为ID
            $ID = $this->create_guid();
            if($Birthday != "")
            {
                $sql = "INSERT INTO person(ID,Name,Gender,Birthday,CardNo,Phone,Role,State,createtime) ";
                $sql .= " VALUES('{$ID}','{$Name}',{$Gender},'{$Birthday}','{$CardNo}','{$Phone}',{$Role},0,'" . date('Y-m-d H:i:s') . "')";
            }
            else
            {
                $sql = "INSERT INTO person(ID,Name,Gender,CardNo,Phone,Role,State,createtime) ";
                $sql .= " VALUES('{$ID}','{$Name}',{$Gender},'{$CardNo}','{$Phone}',{$Role},0,'" . date('Y-m-d H:i:s') . "')";
            }
            $list = mysqli_query($connect, $sql);
            if(mysqli_affected_rows($connect) <= 0)
            {
                mysqli_close($connect);
                $this->error2("The person add failed!", 400);
            } else {
                $dataArray["ID"] = $ID;
                $this->success2($dataArray);
            }
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 3.2 删除人员接口
    // http://mg.acciot.com.tw/api/V2/delete_person
    // http://localhost:9100/api/v2/delete_person
    //http://rhc.test/api/v2/delete_person
    public function delete_person()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'POST') {
            $ID = array();
            if (isset($this->decodedata['ID'])) {
                $ID = $this->decodedata['ID'];
            }
            if (!empty($ID) && !is_array($ID)) {
                $this->error2('ID should be array', 400);
            }
            if (sizeof($ID) > 0) {
                foreach ($ID as $item)
                {
                    if(!is_string($item))
                        $this->error2('ID should be string array!', 400);
                }
                $strID = join("','", $ID);
            }
            else
            {
                $this->error2("ID cannot be null", 400);
            }

            // 数据库连接
            $connect=mysqli_connect($this->decodedata['ip'],$this->decodedata['username'],$this->databaseInfo['password'],$this->decodedata['scheme']);
            if (mysqli_connect_errno($connect))
            {
                $this->error2('Connect MySQL Fail, ' . mysqli_connect_error(), 400);
            }
            // 删除person表的记录
            $sql = "DELETE FROM person WHERE ID in ('" . $strID . "')";
            $list = mysqli_query($connect, $sql);
            if(mysqli_affected_rows($connect) < 0)
            {
                mysqli_close($connect);
                $this->error2("DELETE failed!", 400);
            }

            // 更新device表的Owner
            $sql = "UPDATE device SET `Owner` = '' WHERE `Owner` IN ('" . $strID . "')";
            $result = Db::connect($this->databaseInfo)->query($sql);
            // 插入到logue表中
            $url = $this->GetCurUrl();
            $this->InsertLogue($url, json_encode($this->decodedata), 200, "");
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 3.3 人员列表接口
    // http://mg.acciot.com.tw/api/V2/list_person
    // http://localhost:9100/api/v2/list_person
    //http://rhc.test/api/v2/list_person
    public function list_person()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'POST') {
            $condition = " WHERE 1 ";
            $NoBound = array();
            if (isset($this->decodedata['NoBound'])) {
                $NoBound = $this->decodedata['NoBound'];
            }
            if (!empty($NoBound) && !is_array($NoBound)) {
                $this->error2('NoBound should be array', 400);
            }
            if (sizeof($NoBound) > 0) {
                foreach ($NoBound as $item)
                {
                    if(!is_string($item))
                        $this->error2('NoBound should be string array!', 400);
                }
                $StrNoBound = join("','", $NoBound);
                $condition .= " AND b.`Owner` NOT IN ('{$StrNoBound}')";
            }
            // Role
            $Role = array();
            if (isset($this->decodedata['Role'])) {
                $Role = $this->decodedata['Role'];
            }
            if (!empty($Role) && !is_array($Role)) {
                $this->error2('Role should be array', 400);
            }
            if (sizeof($Role) > 0) {
                foreach ($Role as $item)
                {
                    if(!is_integer($item))
                        $this->error2('Role should be interger array!', 400);
                }
                $StrRole = join(",", $Role);
                $condition .= " AND a.`Role` IN ({$StrRole})";
            }

            $sql = "SELECT a.`ID`,a.`Name`,a.`Gender`,a.`Birthday`,a.`CardNo`,a.`Phone`,a.`Role` ";
            $sql .=" FROM person a LEFT JOIN device b ON a.`ID` = b.`Owner`" . $condition;
            $sql .= " ORDER BY a.`Name`";
            $result = Db::connect($this->databaseInfo)->query($sql);

            // 填充输出的json结构
            // 组合数据
            $dataArray = [];
            $dataArray["total"] = sizeof($result);//当前返回设备的个数
            $subdataArray = [];
            foreach ($result as $item) {
                $item['Gender'] = $item['Gender'] == 1 ? true : false;
                $subdataArray[] = $item;
            }
            $dataArray['result'] = $subdataArray;

            $this->success2($dataArray);
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 3.4 查询人员状态接口
    // http://mg.acciot.com.tw/api/V2/query_person
    // http://localhost:9100/api/v2/query_person
    //http://rhc.test/api/v2/query_person
    public function query_person()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'POST') {
            $ID = "";
            if (isset($this->decodedata['ID'])) {
                $ID = $this->decodedata['ID'];
            }
            if(!empty($ID))
            {
                if(!is_string($ID))
                    $this->error2("The parameter ID must be a string!", 400);
            }
            else
            {
                $this->error2("The parameter ID cannot be null!", 400);
            }

            $condition = " WHERE `Owner` = '{$ID}' ";
            $DeviceType = -1;
            if (isset($this->decodedata['DeviceType'])) {
                $DeviceType = $this->decodedata['DeviceType'];
            }
            if(!is_integer($DeviceType))
            {
                $this->error2("The parameter DeviceType must be a integer!", 400);
            }
            if ($DeviceType !== -1) {
                $condition .= " AND `Type` = " . $DeviceType;
            }

            // 查询person表的记录
            $sql = "SELECT `ID`,`TermID`,`Type` FROM device {$condition}";
            $result = Db::connect($this->databaseInfo)->query($sql);

            // 填充输出的json结构
            // 组合数据
            $dataArray = [];
            $dataArray["total"] = sizeof($result);//当前返回设备的个数
            $dataArray['result'] = $result;

            $this->success2($dataArray);
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 第4章 场景管理口API
    // 4.1 添加场景接口
    // http://mg.acciot.com.tw/api/V2/add_scene
    // http://localhost:9100/api/v2/add_scene
    //http://rhc.test/api/v2/add_scene
    public function add_scene()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'POST') {
            // 基于场景的唯一ID或场景的唯一名称进行删除。这两个参数只要提供一个即可，如果两个都提供，则以ID为主
            $Name = "";
            if (isset($this->decodedata['Name'])) {
                $Name = $this->decodedata['Name'];
            }
            if($Name == "")
            {
                $this->error2("The parameter Name cannot be null!", 400);
            }
            else if(!is_string($Name)){
                $this->error2("The parameter Name must be a string!", 400);
            }

            $BaseAlt = -9999.0;
            if (isset($this->decodedata['BaseAlt'])) {
                $BaseAlt = $this->decodedata['BaseAlt'];
            }
            if($BaseAlt != -9999.0)
            {
                if(!is_float($BaseAlt) && !is_integer($BaseAlt))
                    $this->error2("The BaseAlt must be a interger or a float!", 400);
            }

            $BaseDevice = "";   // BaseDevice是地面基准设备device的设备号TermID
            if (isset($this->decodedata['BaseDevice'])) {
                $BaseDevice = $this->decodedata['BaseDevice'];
            }
            if ($BaseDevice != "" && !is_string($BaseDevice)) {
                $this->error2("The BaseDevice must be a string!", 400);
            }

            // 先判断是否存在，如果提供的场景名称, 在系统中已存在，添加不成功
            $sql = "SELECT count(*) AS num FROM scene WHERE `Name` = '{$Name}'";
            $total = Db::connect($this->databaseInfo)->query($sql);
            if ($total[0]['num'] > 0)  // 已经存在
            {
                $this->error2("The Scene name already exists, cannot be added successfully!", 400);
            }
            // 如果BaseDevice参数提供的TermID在device表中不存在，则添加不成功
            $DeviceID = "";
            if ($BaseDevice != "") {    // TermID
                $sql = "SELECT `ID` FROM device WHERE `TermID` = '{$BaseDevice}'";
                $total = Db::connect($this->databaseInfo)->query($sql);
                if (sizeof($total) <= 0) // 不存在
                {
                    $this->error2("TermID doesn't exist!", 400);
                }
                $DeviceID = $total[0]["ID"];
            }

            // 生成32位GUID，作为ID
            $ID = $this->create_guid();
            $sql = "INSERT INTO scene(ID,Name,BaseAlt,BaseDevice,createtime) ";
            $sql .= " VALUES('{$ID}','{$Name}',{$BaseAlt},'{$DeviceID}','" . date('Y-m-d H:i:s') . "')";
            // 数据库连接
            $connect=mysqli_connect($this->decodedata['ip'],$this->decodedata['username'],$this->databaseInfo['password'],$this->decodedata['scheme']);
            if (mysqli_connect_errno($connect))
            {
                $this->error2('Connect MySQL Fail, ' . mysqli_connect_error(), 400);
            }
            $result = mysqli_query($connect, $sql);
            if(mysqli_affected_rows($connect) < 0)
            {
                mysqli_close($connect);
                $this->error2("The scene add failed!", 400);
            } else {
                $dataArray['ID'] = $ID;
                $this->success2($dataArray);
            }
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 4.2 删除场景接口
    // http://mg.acciot.com.tw/api/V2/delete_scene
    // http://localhost:9100/api/v2/delete_scene
    //http://rhc.test/api/v2/delete_scene
    public function delete_scene()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'POST') {
            $ID = "";
            if (isset($this->decodedata['ID'])) {
                $ID = $this->decodedata['ID'];
            }
            if(!empty($ID) && !is_string($ID))
            {
                $this->error2("The parameter ID must be a string!", 400);
            }

            // 数据库连接
            $connect=mysqli_connect($this->decodedata['ip'],$this->decodedata['username'],$this->databaseInfo['password'],$this->decodedata['scheme']);
            if (mysqli_connect_errno($connect))
            {
                $this->error2("Connect MySQL Fail, " . mysqli_connect_error(), 400);
            }

            // 基于场景的唯一ID或场景的唯一名称进行删除。这两个参数只要提供一个即可，如果两个都提供，则以ID为主
            $Name = "";
            $condition = " WHERE 1 ";
            if ($ID == "") {
                if (isset($this->decodedata['Name'])) {
                    $Name = $this->decodedata['Name'];
                }
                if(!empty($Name))
                {
                    if(!is_string($Name))
                        $this->error2("The parameter Name must be a string!", 400);
                    $condition .= " AND `Name` = '{$Name}'";
                    $sql = "SELECT `ID` FROM scene {$condition}";
                    $result = mysqli_query($connect, $sql);
                    $row = $result->fetch_row();
                    if (count($row) > 0) { // 不存在
                        $ID = $row[0];
                    }
                }
            }
            else
            {
                $condition .= " AND `ID` = '{$ID}'";
            }

            // 删除person表的记录
            $sql = "DELETE FROM scene" . $condition;
            mysqli_query($connect, $sql);
            if(mysqli_affected_rows($connect) < 0)
            {
                mysqli_close($connect);
                $this->error2("Delete scene failed!", 400);
            }
            // 删除Device表里的Sence字段
            $sql = "UPDATE device SET `Scene` = '' WHERE `Scene` = '{$ID}'";
            mysqli_query($connect, $sql);
            if(mysqli_affected_rows($connect) < 0)
            {
                mysqli_close($connect);
                $this->error2("Update device failed!", 400);
            }
            // 插入到logue表中
            $url = $this->GetCurUrl();
            $this->InsertLogue($url, json_encode($this->decodedata), 200, "");
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 4.3 场景列表接口
    // http://mg.acciot.com.tw/api/V2/list_scene
    // http://localhost:9100/api/v2/list_scene
    //http://rhc.test/api/v2/list_scene
    public function list_scene()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'POST') {
            $sql = "SELECT `ID`, `Name`, `BaseAlt`, `BaseDevice` FROM scene";
            $list = Db::connect($this->databaseInfo)->query($sql);

            // 填充输出的json结构
            // 组合数据
            $dataArray = [];
            $dataArray["total"] = sizeof($list);//当前返回设备的个数
            $subDate = [];
            foreach ($list as $item)
            {
                if($item['BaseAlt'] == -9999)
                    unset($item["BaseAlt"]);
                $subDate[] = $item;
            }
            $dataArray['result'] = $subDate;
            $this->success2($dataArray);
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 4.4 地面基准设置接口
    // http://mg.acciot.com.tw/api/V2/update_scene
    // http://localhost:9100/api/v2/update_scene
    //http://rhc.test/api/v2/update_scene
    public function update_scene()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'POST') {
            $ID = "";
            if (isset($this->decodedata['ID'])) {
                $ID = $this->decodedata['ID'];
            }
            if(!empty($ID) && !is_string($ID))
            {
                $this->error2("The parameter ID must be a string!", 400);
            }

            // 基于场景的唯一ID或场景的唯一名称进行删除。这两个参数只要提供一个即可，如果两个都提供，则以ID为主
            $Name = "";
            $condition = " WHERE 1 ";
            if ($ID == "") {
                if (isset($this->decodedata['Name'])) {
                    $Name = $this->decodedata['Name'];
                }
                if(!empty($Name) && !is_string($Name))
                {
                    $this->error2("The parameter Name must be a string!", 400);
                }
                $condition .= " AND `Name` = '{$Name}'";
            }
            else
            {
                $condition .= " AND `ID` = '{$ID}'";
            }

            $BaseAlt = -9999.0;
            if (isset($this->decodedata['BaseAlt'])) {
                $BaseAlt = $this->decodedata['BaseAlt'];
            }
            if($BaseAlt != -9999.0)
            {
                if(!is_float($BaseAlt) && !is_integer($BaseAlt))
                    $this->error2("The BaseAlt must be a interger or a float!", 400);
            }

            // 数据库连接
            $connect=mysqli_connect($this->decodedata['ip'],$this->decodedata['username'],$this->databaseInfo['password'],$this->decodedata['scheme']);
            if (mysqli_connect_errno($connect))
            {
                $this->error2('Connect MySQL Fail, ' . mysqli_connect_error(), 400);
            }

            $BaseDevice = "";   // BaseDevice是地面基准设备device的设备号TermID
            if (isset($this->decodedata['BaseDevice'])) {
                $BaseDevice = $this->decodedata['BaseDevice'];
            }
            if ($BaseDevice != "") {
                if(!is_string($BaseDevice))
                    $this->error2("The BaseDevice must be a string!", 400);
                $sql99 = "SELECT `ID` FROM device WHERE `TermID` = '{$BaseDevice}'";
                $result = mysqli_query($connect, $sql99);
                if(mysqli_affected_rows($connect) <= 0)
                {
                    mysqli_close($connect);
                    $this->error2("The BaseDevice doesn't exists!", 400);
                }
                $row = $result->fetch_row();
                $BaseDevice = $row[0];
            }
            $sql = null;
            if($BaseAlt != -9999.0 && $BaseDevice != "")
            {
                $sql = "UPDATE scene SET `BaseAlt` = {$BaseAlt},`BaseDevice` = '{$BaseDevice}' " . $condition;
            }
            else if($BaseAlt != -9999.0 && $BaseDevice == "")
            {
                $sql = "UPDATE scene SET `BaseAlt` = {$BaseAlt},`BaseDevice` = '{$BaseDevice}' " . $condition;
            }
            else if($BaseAlt == -9999.0 && $BaseDevice != "")
            {
                $sql = "UPDATE scene SET `BaseDevice` = '{$BaseDevice}' " . $condition;
            }
            else if($BaseDevice == "")
            {
                // 如果提供一个空的BaseDevice就是帮这个场景的BaseDevice属性置空
                $sql = "UPDATE scene SET `BaseDevice` = '' " . $condition;
            }

            // 先判断是否存在，如果提供的场景名称, 在系统中已存在，添加不成功
            $sql_0 = "SELECT count(*) AS num FROM scene " . $condition;
            $total = mysqli_query($connect, $sql_0);
            if(mysqli_affected_rows($connect) < 0)
            {
                mysqli_close($connect);
                $this->error2("The Scene doesn't exists!", 400);
            }

            if(!empty($sql))
            {
                // 更新scene表
                $total = mysqli_query($connect, $sql);
                if(mysqli_affected_rows($connect) < 0)
                    $this->error2("The Scene update failed!", 400);
            }
            mysqli_close($connect);
            // 成功，写LOG
            // 插入到logue表中
            $url = $this->GetCurUrl();
            $this->InsertLogue($url, json_encode($this->decodedata), 200, "");
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 4.5 获取场景所属设备接口
    // http://mg.acciot.com.tw/api/V2/list_scene_device
    // http://localhost:9100/api/v2/list_scene_device
    //http://rhc.test/api/v2/list_scene_device
    public function list_scene_device()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'POST') {
            $ID = "";
            if (isset($this->decodedata['ID'])) {
                $ID = $this->decodedata['ID'];
            }
            if(!empty($ID) && !is_string($ID))
            {
                $this->error2("The parameter ID must be a string!", 400);
            }

            // 基于场景的唯一ID或场景的唯一名称进行删除。这两个参数只要提供一个即可，如果两个都提供，则以ID为主
            $Name = "";
            if ($ID == "") {
                if (isset($this->decodedata['Name'])) {
                    $Name = $this->decodedata['Name'];
                }
                if(!empty($Name) && !is_string($Name))
                {
                    $this->error2("The parameter Name must be a string!", 400);
                }
                // 根据Name查找ID
                $sql = "SELECT `ID` FROM scene WHERE `Name` = '{$Name}'";
                $result = Db::connect($this->databaseInfo)->query($sql);
                if (count($result) <= 0) { // 不存在
                    $this->error2("The scene doesn't exist!", 400);
                }
                $ID = $result[0]['ID'];
            }

            $sql0 = "SELECT COUNT(*) as num FROM device WHERE `Scene` = '{$ID}'";
            $sql1 = "SELECT `ID`, `TermID`, `Alias`, `Type` FROM device WHERE `Scene` = '{$ID}'";
            $total = Db::connect($this->databaseInfo)->query($sql0);
            $list = Db::connect($this->databaseInfo)->query($sql1);

            // 填充输出的json结构
            // 组合数据
            $dataArray = [];
            $dataArray["total"] = $total[0]['num'];//当前返回设备的个数
            $dataArray["result"] = $list;
            // 输出
            $this->success2($dataArray);
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 4.6 向场景添加设备接口 test...
    // http://mg.acciot.com.tw/api/V2/add_scene_device
    // http://localhost:9100/api/v2/add_scene_device
    //http://rhc.test/api/v2/add_scene_device
    public function add_scene_device()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'POST') {
            $ID = "";
            if (isset($this->decodedata['ID'])) {
                $ID = $this->decodedata['ID'];
            }
            if(!empty($ID) && !is_string($ID))
            {
                $this->error2("The parameter ID must be a string!", 400);
            }

            // 数据库连接
            $connect=mysqli_connect($this->decodedata['ip'],$this->decodedata['username'],$this->databaseInfo['password'],$this->decodedata['scheme']);
            if (mysqli_connect_errno($connect))
            {
                $this->error2("Connect MySQL Fail, " . mysqli_connect_error(), 400);
            }

            // 基于场景的唯一ID或场景的唯一名称进行删除。这两个参数只要提供一个即可，如果两个都提供，则以ID为主
            $Name = "";
            if ($ID == "") {
                if (isset($this->decodedata['Name'])) {
                    $Name = $this->decodedata['Name'];
                }
                if(!empty($Name) && !is_string($Name))
                {
                    $this->error2("The parameter Name must be a string!", 400);
                }
                // 根据Name查找ID
                $sql = "SELECT `ID` FROM scene WHERE `Name` = '{$Name}'";
                $result = mysqli_query($connect, $sql);
                $row = $result->fetch_row();
                if (count($row) <= 0) { // 不存在
                    mysqli_close($connect);
                    $this->error2("The scene doesn't exist!", 400);
                }
                $ID = $row[0];
            }

            // 判断TermID
            $TermID = array();
            if (isset($this->decodedata['TermID'])) {
                $TermID = $this->decodedata['TermID'];
            }
            if (!empty($TermID) && !is_array($TermID)) {
                $this->error2('TermID should be array', 400);
            }
            if (sizeof($TermID) > 0) {
                foreach ($TermID as $item)
                {
                    if(!is_string($item))
                        $this->error2('TermID should be string array!', 400);
                }
                $strTermID = join("','", $TermID);
            }
            else
            {
                $this->error2("TermID cannot be null", 400);
            }
            // 则添加device表里的场景scene字段。
            $sql = "UPDATE device SET `Scene` = '{$ID}' WHERE `TermID` in ('{$strTermID}')";
            mysqli_query($connect, $sql);
            if(mysqli_affected_rows($connect) <= 0)
            {
                mysqli_close($connect);
                $this->error2("Update database failed!", 400);
            }

            // 成功，写LOG
            // 插入到logue表中
            $url = $this->GetCurUrl();
            $this->InsertLogue($url, json_encode($this->decodedata), 200, "");
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 4.7 删除或清空场景中设备接口
    // http://mg.acciot.com.tw/api/V2/clear_scene_device
    // http://localhost:9100/api/v2/clear_scene_device
    //http://rhc.test/api/v2/clear_scene_device
    public function clear_scene_device()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'POST') {
            $ID = "";
            if (isset($this->decodedata['ID'])) {
                $ID = $this->decodedata['ID'];
            }
            if(!empty($ID) && !is_string($ID))
            {
                $this->error2("The parameter ID must be a string!", 400);
            }
            // 基于场景的唯一ID或场景的唯一名称进行删除。这两个参数只要提供一个即可，如果两个都提供，则以ID为主
            $condition = " WHERE 1";
            $Name = "";
            if ($ID == "") {
                if (isset($this->decodedata['Name'])) {
                    $Name = $this->decodedata['Name'];
                }
                if(!empty($Name) && !is_string($Name))
                {
                    $this->error2("The parameter Name must be a string!", 400);
                }
                // 根据Name查找ID
                $condition .= " AND b.`Name` = '{$Name}'";  // b是scene
            }
            else
            {
                $condition .= " AND b.`ID` = '{$ID}'";  // b是scene
            }
            // 判断TermID
            $TermID = array();
            if (isset($this->decodedata['TermID'])) {
                $TermID = $this->decodedata['TermID'];
            }
            if (!empty($TermID) && !is_array($TermID)) {
                $this->error2('TermID should be array', 400);
            }
            if (sizeof($TermID) > 0) {
                foreach ($TermID as $item)
                {
                    if(!is_string($item))
                        $this->error2('TermID should be string!', 400);
                }
                $strTermID = join("','", $TermID);
                $condition .= " AND a.`TermID` in ('{$strTermID}')";
            }
            // 数据库连接
            $connect=mysqli_connect($this->decodedata['ip'],$this->decodedata['username'],$this->databaseInfo['password'],$this->decodedata['scheme']);
            if (mysqli_connect_errno($connect))
            {
                $this->error2("Connect MySQL Fail, " . mysqli_connect_error(), 400);
            }
            // 则清空device表里的场景scene字段。
            $sql = "UPDATE device a INNER JOIN scene b ON a.`Scene` = b.`ID` SET a.`Scene` = '' {$condition}";
            mysqli_query($connect, $sql);
            if(mysqli_affected_rows($connect) < 0)
            {
                mysqli_close($connect);
                $this->error2("Update database failed!", 400);
            }

            // 成功，写LOG
            // 插入到logue表中
            $url = $this->GetCurUrl();
            $this->InsertLogue($url, json_encode($this->decodedata), 200, "");
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 5.1 添加设备接口
    //http://rhc.test/api/v2/add_device?Alias=llje&TermID=baa2
    public function add_device()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        }
        else if ($method == 'POST') {
            $TermID = "";   // 必填
            if (isset($this->decodedata['TermID'])) {
                $TermID = $this->decodedata['TermID'];
            }
            if(!is_string($TermID) || empty($TermID))
            {
                $this->error2("The parameter TermID cannot be null and must be a string, cannot be added successfully!", 400);
            }
            $Type = -1;     // 必填
            if (isset($this->decodedata['Type'])) {
                $Type = $this->decodedata['Type'];
            }
            if(!is_integer($Type))
            {
                $this->error2("The parameter Type must be a integer!", 400);
            }
            if($Type == -1)
            {
                $this->error2("The parameter Type error!", 400);
            }
            $Alias = "";
            if (isset($this->decodedata['Alias'])) {
                $Alias = $this->decodedata['Alias'];
            }
            if(!is_string($Alias))
            {
                $this->error2("The parameter Alias must be a string!", 400);
            }
            $Owner = "";
            if (isset($this->decodedata['Owner'])) {
                $Owner = $this->decodedata['Owner'];
            }
            if(!is_string($Owner))
            {
                $this->error2("The parameter Owner must be a string!", 400);
            }
            // 先判断是否存在，如果在系统中已存在，添加不成功
            // TermID验证
            $sql = "SELECT COUNT(*) AS num FROM device WHERE `TermID` = '{$TermID}'";
            $total = Db::connect($this->databaseInfo)->query($sql);
            if ($total[0]['num'] > 0)  // 已经存在
            {
                $this->error2("The TermID already exists, cannot be added successfully!", 400);
            }
            // Type验证
            $sql = "SELECT COUNT(*) AS num FROM device_type WHERE `Type` = {$Type}";
            $total = Db::connect($this->databaseInfo)->query($sql);
            if ($total[0]['num'] == 0)  // 不存在
            {
                $this->error2("The Type does not exist, cannot be added successfully!", 400);
            }
            // Owner验证
            if($Owner != "")
            {
                // 这个owner人不存在
                $sql = "SELECT COUNT(*) AS num FROM person WHERE `Name` = '{$Owner}'";
                $total = Db::connect($this->databaseInfo)->query($sql);
                if ($total[0]['num'] == 0)  // 不存在
                {
                    $this->error2("The Owner does not exist, cannot be added successfully!", 400);
                }
                // 这个owner已经有同样类型设备
                $sql = "SELECT COUNT(*) AS num FROM device WHERE `Owner` = '{$Owner}' AND `Type` = {$Type}";
                $total = Db::connect($this->databaseInfo)->query($sql);
                if ($total[0]['num'] > 0)  // 已经存在
                {
                    $this->error2("The Owner and Type already exists, cannot be added successfully!", 400);
                }
            }

            $ID = $this->create_guid();
            $createtime = date('Y-m-d H:i:s');
            $sql = "INSERT INTO device (`ID`, `Type`, `Alias`, `Owner`, `TermID`, `createtime`) ";
            $sql .="VALUES ('{$ID}', {$Type}, '{$Alias}', '{$Owner}', '{$TermID}', '{$createtime}');";
            // 数据库连接
            $connect=mysqli_connect($this->decodedata['ip'],$this->decodedata['username'],$this->databaseInfo['password'],$this->decodedata['scheme']);
            if (mysqli_connect_errno($connect))
            {
                $this->error2('Connect MySQL Fail, ' . mysqli_connect_error(), 400);
            }
            $result = mysqli_query($connect, $sql);
            if(mysqli_affected_rows($connect) <= 0)
            {
                mysqli_close($connect);
                $this->error2("The device add failed!", 400);
            }
            else
            {
                $data = [];
                $data["ID"] = $ID;
                $this->success2($data);
            }
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 5.2 删除设备接口
    //http://rhc.test/api/v2/delete_device
    public function delete_device()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        }
        else if ($method == 'POST') {
            $ID = array();
            if (isset($this->decodedata['ID'])) {
                $ID = $this->decodedata['ID'];
            }
            if (!is_array($ID)) {
                $this->error2('ID should be array', 400);
            }
            $ID = array_filter($ID);
            if (sizeof($ID) > 0) {
                foreach ($ID as $item)
                {
                    if(!is_string($item))
                        $this->error2('ID should be string array!', 400);
                }
                $strID = join("','", $ID);
                $condition = " `ID` in ('{$strID}')";
            }
            else
            {
                // 判断TermID
                $TermID = array();
                if (isset($this->decodedata['TermID'])) {
                    $TermID = $this->decodedata['TermID'];
                }
                if (!is_array($TermID)) {
                   $this->error2('TermID should be array', 400);
                }
                if (sizeof($TermID) > 0) {
                    foreach ($TermID as $item)
                    {
                        if(!is_string($item))
                            $this->error2('TermID should be string array!', 400);
                    }
                    $strTermID = join("','", $TermID);
                    $condition = " `TermID` in ('{$strTermID}')";
                }
            }
            $sql = "DELETE FROM device WHERE {$condition}";
            $result = Db::connect($this->databaseInfo)->query($sql);
            $sql = "SELECT `ID` FROM device WHERE {$condition}";
            $list = Db::connect($this->databaseInfo)->query($sql);
            if(sizeof($list) > 0)
            {
                $strID = [];
                foreach ($list as $item)
                {
                    $strID[] = $item['ID'];
                }
                $strID = join("','", $strID);
                $this->error2('These (' + $strID + ') delete failed, please try again!', 400);
            }
            else
            {
                // 成功，写LOG
                // 插入到logue表中
                $url = $this->GetCurUrl();
                $this->InsertLogue($url, json_encode($this->decodedata), 200, "");
            }
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 5.3 设备人员绑定接口
    //http://rhc.test/api/v2/bind_device
    public function bind_device()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        }
        else if ($method == 'POST') {
            $ID = "";
            if (isset($this->decodedata['ID'])) {
                $ID = $this->decodedata['ID'];
            }
            if(!is_string($ID))
            {
                $this->error2("The parameter ID must be a string!", 400);
            }
            $TermID = "";
            if (isset($this->decodedata['TermID'])) {
                $TermID = $this->decodedata['TermID'];
            }
            if(!is_string($TermID))
            {
                $this->error2("The parameter TermID must be a string!", 400);
            }
            $Owner = "";
            if (isset($this->decodedata['Owner'])) {
                $Owner = $this->decodedata['Owner'];
            }
            if(!empty($Owner) && !is_string($Owner))
            {
                $this->error2("The parameter Owner must be a string!", 400);
            }

            if(empty($ID))
            {
                if(empty($TermID))
                {
                    $this->error2("The parameter ID and TermID must have one!", 400);
                }
                $condition = " TermID = '{$TermID}'";
            }
            else
            {
                $condition = " ID = '{$ID}'";
            }

            // 数据库连接
            $connect=mysqli_connect($this->decodedata['ip'],$this->decodedata['username'],$this->databaseInfo['password'],$this->decodedata['scheme']);
            if (mysqli_connect_errno($connect))
            {
                $this->error2("Connect MySQL Fail, " . mysqli_connect_error(), 400);
            }

            // 先判断ID和TermID是否存在？
            $sql = "SELECT COUNT(*) as num FROM device WHERE " . $condition;
            $result = mysqli_query($connect, $sql);
            $row = $result->fetch_row();
            $num = $row[0];
            if ($num == 0) { // 不存在
                mysqli_close($connect);
                $this->error2("The device doesn't exist!", 400);
            }

            // 判断Owner是不是为空，为空就进行解绑
            if(empty($Owner))
            {
                // 进行解绑
                $sql = "UPDATE device SET `Owner` ='' WHERE " . $condition;
                mysqli_query($connect, $sql);
                if(mysqli_affected_rows($connect) < 0)
                {
                    mysqli_close($connect);
                    $this->error2("Update database failed!", 400);
                }
            }
            else
            {
                // 先判断这个owner的人是否存在？
                $sql = "SELECT COUNT(*) AS num FROM person WHERE `ID` = '{$Owner}'";
                $result = mysqli_query($connect, $sql);
                $row = $result->fetch_row();
                $num = $row[0];
                if ($num == 0) { // 不存在
                    mysqli_close($connect);
                    $this->error2("The Owner doesn't exist!", 400);
                }

                // 先提取ID和TermID的Type，然后再
                // Type验证
                $sql = "SELECT `Type`,`Owner` FROM device WHERE " . $condition;
                $result = mysqli_query($connect, $sql);
                if ($result->num_rows > 0) { // 存在
                    // 输出数据
                    $row = $result->fetch_row();
                    $Type = $row[0];    // Type
                    // 判断同一个Owner，有没有其他同类型type的device
                    $sql = "SELECT `Type` FROM device WHERE `Owner` = '{$Owner}' AND `Type` = {$Type} AND !(" . $condition .")";
                    $result = mysqli_query($connect, $sql);
                    if ($result->num_rows > 0) { // 存在
                        mysqli_close($connect);
                        $this->error2("The owner already has other devices of the same type!", 400);
                    }
                    // 如果设备都已绑定到其它人员，而非此指定人员，则算函数执行不成功
                    $Owner = $row[1];
                    if(!empty($Owner))
                    {
                        mysqli_close($connect);
                        $this->error2("The device already has bind Owner!", 400);
                    }
                    // 开始绑定
                    $sql = "UPDATE device SET `Owner` = '{$Owner}' WHERE " . $condition;
                    $result = mysqli_query($connect, $sql);
                    if(mysqli_affected_rows($connect) < 0)
                    {
                        mysqli_close($connect);
                        $this->error2("Update database failed!", 400);
                    }
                }
            }
            mysqli_close($connect);

            // 成功，写LOG
            // 插入到logue表中
            $url = $this->GetCurUrl();
            $this->InsertLogue($url, json_encode($this->decodedata), 200, "");
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 5.4 修改设备别名接口
    //http://rhc.test/api/v2/alias_device
    public function alias_device()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        }
        else if ($method == 'POST') {
            $ID = "";
            if (isset($this->decodedata['ID'])) {
                $ID = $this->decodedata['ID'];
            }
            if(!is_string($ID))
            {
                $this->error2("The parameter ID must be a string!", 400);
            }
            $TermID = "";
            if (isset($this->decodedata['TermID'])) {
                $TermID = $this->decodedata['TermID'];
            }
            if(!is_string($TermID))
            {
                $this->error2("The parameter TermID must be a string!", 400);
            }
            $Alias = "";
            if (isset($this->decodedata['Alias'])) {
                $Alias = $this->decodedata['Alias'];
            }
            if(!empty($Alias) && !is_string($Alias))
            {
                $this->error2("The parameter Alias must be a string!", 400);
            }

            if(empty($ID))
            {
                if(empty($TermID))
                {
                    $this->error2("The parameter ID and TermID must have one!", 400);
                }
                $condition = " TermID = '{$TermID}'";
            }
            else
            {
                $condition = " ID = '{$ID}'";
            }

            // 数据库连接
            $connect=mysqli_connect($this->decodedata['ip'],$this->decodedata['username'],$this->databaseInfo['password'],$this->decodedata['scheme']);
            if (mysqli_connect_errno($connect))
            {
                $this->error2('Connect MySQL Fail, ' . mysqli_connect_error(), 400);
            }

            // 先判断ID和TermID是否存在？
            $sql = "SELECT COUNT(*) as num FROM device WHERE " . $condition;
            $result = mysqli_query($connect, $sql);
            $row = $result->fetch_row();
            $num = $row[0];
            if ($num == 0) { // 不存在
                mysqli_close($connect);
                $this->error2("The device doesn't exist!", 400);
            }

            // 判断Alias是不是为空，为空就进行解绑
            if(empty($Alias))
            {
                // 进行解绑
                $sql = "UPDATE device SET `Alias` ='' WHERE {$condition}";
                mysqli_query($connect, $sql);
                if(mysqli_affected_rows($connect) < 0)
                {
                    mysqli_close($connect);
                    $this->error2("Update database failed!", 400);
                }
            }
            else
            {
                $sql = "UPDATE device SET `Alias` = '{$Alias}' WHERE " . $condition;
                $result = mysqli_query($connect, $sql);
                if(mysqli_affected_rows($connect) < 0)
                {
                    mysqli_close($connect);
                    $this->error2("Update database failed!", 400);
                }
            }
            mysqli_close($connect);
            // 成功，写LOG
            // 插入到logue表中
            $url = $this->GetCurUrl();
            $this->InsertLogue($url, json_encode($this->decodedata), 200, "");
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 5.5 设定设备轮廓接口
    //http://rhc.test/api/v2/outline_device
    public function outline_device()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        }
        else if ($method == 'POST') {
            $ID = "";
            if (isset($this->decodedata['ID'])) {
                $ID = $this->decodedata['ID'];
            }
            if(!is_string($ID))
            {
                $this->error2("The parameter ID must be a string!", 400);
            }
            $TermID = "";
            if (isset($this->decodedata['TermID'])) {
                $TermID = $this->decodedata['TermID'];
            }
            if(!is_string($TermID))
            {
                $this->error2("The parameter TermID must be a string!", 400);
            }
            // ID与TermID必须有一个
            if(empty($ID))
            {
                if(empty($TermID))
                {
                    $this->error2("The parameter ID and TermID must have one!", 400);
                }
                $condition = " TermID = '{$TermID}'";
            }
            else
            {
                $condition = " `ID` = '{$ID}'";
            }

            // Outline是object
            $Outline = [];
            if (isset($this->decodedata['Outline'])) {
                $Outline = $this->decodedata['Outline'];
            }

            // 数据库连接
            $connect=mysqli_connect($this->decodedata['ip'],$this->decodedata['username'],$this->databaseInfo['password'],$this->decodedata['scheme']);
            if (mysqli_connect_errno($connect))
            {
                $this->error2('Connect MySQL Fail, ' . mysqli_connect_error(), 400);
            }
            if(is_array($Outline) && sizeof($Outline) == 0)
            {
                // 进行解绑
                $sql = "UPDATE device SET `Outline` ='' WHERE " . $condition;
                mysqli_query($connect, $sql);
                if(mysqli_affected_rows($connect) < 0)
                {
                    mysqli_close($connect);
                    $this->error2("Update database failed!", 400);
                }
                mysqli_close($connect);
                return;
            }
            else if(!is_array($Outline))
            {
                $this->error2("The parameter Outline must be a object!", 400);
            }

            // 先判断ID和TermID是否存在？
            $sql = "SELECT COUNT(*) as num FROM device WHERE " . $condition;
            $result = mysqli_query($connect, $sql);
            $row = $result->fetch_row();
            $num = $row[0];
            if ($num == 0) { // 不存在
                mysqli_close($connect);
                $this->error2("The device doesn't exist!", 400);
            }

            if(empty($Outline))
            {
                // 进行解绑
                $sql = "UPDATE device SET `Outline` ='' WHERE " . $condition;
                mysqli_query($connect, $sql);
                if(mysqli_affected_rows($connect) < 0)
                {
                    mysqli_close($connect);
                    $this->error2("Update database failed!", 400);
                }
            }
            else
            {
                // 一定要检查Outline的a,b 参数与Type匹配，且a, b不能小于或等于０。在参数不匹配，添加不成功
                if($Outline['Type'] != 0 && $Outline['Type'] != 1 && $Outline['Type'] != 2 && $Outline['Type'] != 3)
                {
                    mysqli_close($connect);
                    $this->error2("The parameter Type of Device can only be 0,1,2,3!!", 400);
                }
                else
                {
                    // 先查Type，看有没有该Type
                    $sql = "SELECT COUNT(*) AS num FROM outline WHERE `Type` = {$Outline['Type']}";
                    $result = mysqli_query($connect, $sql);
                    $row = $result->fetch_row();
                    $num = $row[0];
                    if ($num == 0) { // 不存在
                        mysqli_close($connect);
                        $this->error2("The parameter Type of Outline doesn't exist!", 400);
                    }
                    // 一定要检查Outline的a,b 参数与Type匹配，且a, b不能小于或等于０。在参数不匹配，添加不成功
                    if($Outline['Type'] == 0 || $Outline['Type'] == 1)
                    {
                        // 1)如果Type为０或１：　忽略此a, b参数；
                        // 先从outline表里，查询有没有，如果没有，就添加到outline表
                        $sql = "SELECT `ID` FROM outline WHERE `Type` = {$Outline['Type']}";
                        $result = mysqli_query($connect, $sql);
                        $outline_id = $this->create_guid();
                        if ($result->num_rows <= 0) { // 不存在
                            // 添加一个outline到outline表里
                            $createtime = date('Y-m-d H:i:s');
                            $sql = "INSERT INTO outline (`ID`, `Type`, `CreateTime`) VALUES ('{$outline_id}', {$Outline['Type']}, '{$createtime}')";
                            $result = mysqli_query($connect, $sql);
                            if(mysqli_affected_rows($connect) <= 0)
                            {
                                mysqli_close($connect);
                                $this->error2("Insert outline table failed!", 400);
                            }
                        }
                        else
                        {
                            $row = $result->fetch_row();
                            $outline_id = $row[0];
                        }
                        // 更新device表的outline字段
                        $sql = "UPDATE device SET `Outline` = '{$outline_id}' WHERE " . $condition;
                        $result = mysqli_query($connect, $sql);
                        if(mysqli_affected_rows($connect) < 0)
                        {
                            mysqli_close($connect);
                            $this->error2("Update database failed!", 400);
                        }
                    }
                    else if($Outline['Type'] == 2)
                    {
                        if(empty($Outline['a']))
                        {
                            mysqli_close($connect);
                            $this->error2("The parameter a of Outline cannot be empty when Type is 2!", 400);
                        }
                        else
                        {
                            if($Outline['a'] <= 0)
                            {
                                mysqli_close($connect);
                                $this->error2("The parameter a of Outline cannot be less than 0!", 400);
                            }
                        }
                        // 先从outline表里，查询有没有，如果没有，就添加到outline表
                        $sql = "SELECT `ID` FROM outline WHERE `Type` = {$Outline['Type']} AND `a` = {$Outline['a']}";
                        $result = mysqli_query($connect, $sql);
                        $outline_id = $this->create_guid();
                        if ($result->num_rows <= 0) { // 不存在
                            // 添加一个outline到outline表里
                            $createtime = date('Y-m-d H:i:s');
                            $sql = "INSERT INTO outline (`ID`, `Type`, `a`, `CreateTime`) VALUES ('{$outline_id}', {$Outline['Type']}, {$Outline['a']}, '{$createtime}')";
                            $result = mysqli_query($connect, $sql);
                            if(mysqli_affected_rows($connect) <= 0)
                            {
                                mysqli_close($connect);
                                $this->error2("Insert outline table failed!", 400);
                            }
                        }
                        else
                        {
                            $row = $result->fetch_row();
                            $outline_id = $row[0];
                        }
                        // 更新device表的outline字段
                        $sql = "UPDATE device SET `Outline` = '{$outline_id}' WHERE " . $condition;
                        $result = mysqli_query($connect, $sql);
                    }
                    else if($Outline['Type'] == 3)
                    {
                        if(empty($Outline['a']) || empty($Outline['b']))
                        {
                            mysqli_close($connect);
                            $this->error2("The parameter a or b of Outline cannot be empty when Type is 3!", 400);
                        }
                        else
                        {
                            if($Outline['a'] <= 0 || $Outline['b'] <= 0)
                            {
                                mysqli_close($connect);
                                $this->error2("The parameter a or b of Outline cannot be less than 0!", 400);
                            }
                        }
                        // 先从outline表里，查询有没有，如果没有，就添加到outline表
                        $sql = "SELECT `ID` FROM outline WHERE `Type` = {$Outline['Type']} AND `a` = {$Outline['a']} AND `b` = {$Outline['b']}";
                        $result = mysqli_query($connect, $sql);
                        $outline_id = $this->create_guid();
                        if ($result->num_rows <= 0) { // 不存在
                            // 添加一个outline到outline表里
                            $createtime = date('Y-m-d H:i:s');
                            $sql = "INSERT INTO outline (`ID`, `Type`, `a`, `b`, `CreateTime`) VALUES ('{$outline_id}', {$Outline['Type']}, {$Outline['a']}, {$Outline['b']}, '{$createtime}')";
                            $result = mysqli_query($connect, $sql);
                            if(mysqli_affected_rows($connect) <= 0)
                            {
                                mysqli_close($connect);
                                $this->error2("Insert outline table failed!", 400);
                            }
                        }
                        else
                        {
                            $row = $result->fetch_row();
                            $outline_id = $row[0];
                        }
                        // 更新device表的outline字段
                        $updatetime = date('Y-m-d H:i:s');
                        $sql = "UPDATE device SET `Outline` = '{$outline_id}' WHERE " . $condition;
                        $result = mysqli_query($connect, $sql);
                        if(mysqli_affected_rows($connect) < 0)
                        {
                            mysqli_close($connect);
                            $this->error2("Update database failed!", 400);
                        }
                    }
                    else {
                        $this->error2("The parameter Type of Device can only be 0,1,2,3!", 400);
                    }
                }
            }
            mysqli_close($connect);
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 5.6 查询多个设备状态接口
    //http://rhc.test/api/v2/query_device
    public function query_device()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        }
        else if ($method == 'POST') {
            $ID = array();
            if (isset($this->decodedata['ID'])) {
                $ID = $this->decodedata['ID'];
            }
            if (!is_array($ID)) {
                $this->error2('ID should be array', 400);
            }
            $ID = array_filter($ID);
            if (sizeof($ID) > 0) {
                foreach ($ID as $item)
                {
                    if(!is_string($item))
                        $this->error2('ID should be string array!', 400);
                }
                $strID = join("','", $ID);
                $condition = " `ID` in ('{$strID}')";
            }
            else
            {
                // 判断TermID
                $TermID = array();
                if (isset($this->decodedata['TermID'])) {
                    $TermID = $this->decodedata['TermID'];
                }
                if (!is_array($TermID)) {
                    $this->error2('TermID should be array', 400);
                }
                $TermID = array_filter($TermID);
                if (sizeof($TermID) > 0) {
                    foreach ($TermID as $item)
                    {
                        if(!is_string($item))
                            $this->error2('TermID should be string array!', 400);
                    }
                    $strTermID = join("','", $TermID);
                    $condition = " `TermID` in ('{$strTermID}')";
                }
            }
            // Outline不为空的先取一下
            $sql = "SELECT * FROM device WHERE {$condition}";
            $list = Db::connect($this->databaseInfo)->query($sql);
            // 填充输出的json结构
            // 组合数据
            $dataArray = [];
            $dataArray["total"] = sizeof($list);//当前返回设备的个数
            $subdataArray = [];
            foreach($list as $item)
            {
                // 组合subdataArray
                $data = [
                    'ID' => "",
                    'TermID' => "",
                    'Alias' => null,
                    'Type' => -1,
                    'State' => 0,
                    'Working' => 0,
                    'Owner' => null,
                    'Scene' => null,
                    'Outline' => null,
                    'LastTime' => ""
                ];
                // 日期转换为时间戳
                $data['ID'] = $item['ID'];
                $data['TermID'] = $item['TermID'];
                $data['Alias'] = $item['Alias'];
                $data['Type'] = $item['Type'];
                $data['State'] = $item['State'];
                $data['Working'] = $item['Working'];
                // Owner object
                if(!empty($item['Owner']))
                {
                    $sql = "SELECT `ID`,`Name` FROM person WHERE `ID` = '{$item['Owner']}'";
                    $Ownerlist = Db::connect($this->databaseInfo)->query($sql);
                    if(sizeof($Ownerlist) > 0)
                    {
                        $subOwner = [
                            "ID" => "",
                            "Name" => ""
                        ];
                        $subOwner = $Ownerlist;
                    }
                    // 赋值
                    $data['Owner'] = $subOwner;
                }
                // Scene
                if(!empty($item['Scene']))
                {
                    $sql = "SELECT `Name` FROM scene WHERE `ID` = '{$item['Scene']}'";
                    $Scenelist = Db::connect($this->databaseInfo)->query($sql);
                    if(sizeof($Scenelist) > 0)
                    {
                        $data['Scene'] = $Scenelist[0]['Name'];
                    }
                }
                // Outline object
                if(!empty($item['Outline']))
                {
                    $sql = "SELECT `Type`,`a`,`b` FROM outline WHERE `ID` = '{$item['Outline']}'";
                    $Outlinelist = Db::connect($this->databaseInfo)->query($sql);
                    if(sizeof($Outlinelist) > 0)
                    {
                        $subOutline = [
                            "Type" => -1,
                            "a" => null,
                            "b" => null
                        ];
                        $subOutline = $Outlinelist;
                    }
                    // 赋值
                    $data['Outline'] = $subOutline;
                }
                $data['LastTime'] = $item['LastTime'];
                // 统一赋值
                $subdataArray[] = $data;
            }
            $dataArray['result'] = $subdataArray;
            // 输出
            $this->success2($dataArray);
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 5.7 设备列表接口
    // http://mg.acciot.com.tw/api/V2/list_device
    // http://localhost:9100/api/v2/list_device
    //http://rhc.test/api/v2/list_device
    public function list_device()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'POST') {
            // 判断TermID
            $TermID = "";
            if (isset($this->decodedata['TermID'])) {
                $TermID = $this->decodedata['TermID'];
            }
            if(!is_string($TermID))
            {
                $this->error2("The parameter TermID must be a string!", 400);
            }
            if(!empty($TermID))
            {
                $condition = " TermID = '{$TermID}'";
            }
            // Alias
            $Alias = "";
            if (isset($this->decodedata['Alias'])) {
                $Alias = $this->decodedata['Alias'];
            }
            if(!empty($Alias) && !is_string($Alias))
            {
                $this->error2("The parameter Alias must be a string!", 400);
            }
            // Bound
            $Bound = -1;
            if (isset($this->decodedata['Bound'])) {
                $Bound = $this->decodedata['Bound'];
            }
            if($Bound !== -1 && !is_bool($Bound))
            {
                $this->error2("The parameter Bound should be a bool!", 400);
            }
            if($Bound !== -1 && $Bound != 1)
                $Bound = 0;

            // Oneline
            $Online = -1;
            if (isset($this->decodedata['Online'])) {
                $Online = $this->decodedata['Online'];
            }
            if($Online !== -1 && !is_bool($Online))
            {
                $this->error2("The parameter Online should be a bool!", 400);
            }
            if($Online !== -1 && $Online != 1)
                $Online = 0;

            // Type
            $Type = -1;
            if (isset($this->decodedata['Type'])) {
                $Type = $this->decodedata['Type'];
            }
            if(!empty($Type) && !is_integer($Type))
            {
                $this->error2("The parameter Type should be a Interger!", 400);
            }

            // PageSize
            $PageSize = 100;
            if (isset($this->decodedata['PageSize'])) {
                $PageSize = $this->decodedata['PageSize'];
            }
            if($PageSize != 100)
            {
                if(!is_integer($PageSize))
                    $this->error2("The parameter PageSize should be a Interger!", 400);
                if ($PageSize <= 0) {
                    $this->error2("pageSize must be greater than 0!", 400);
                }
            }
            // PageIndex
            $PageIndex = 0;
            if (isset($this->decodedata['PageIndex'])) {
                $PageIndex = $this->decodedata['PageIndex'];
            }
            if($PageIndex != 0)
            {
                if(!is_integer($PageIndex))
                    $this->error2("The parameter PageIndex should be a Interger!", 400);
                if ($PageIndex < 0) {
                    $this->error2("PageIndex must be greater than or equal to 0!", 400);
                }
            }

            $condition = " WHERE 1 ";
            if (!empty($TermID)) {
                $condition .= " AND a.`TermID` = '{$TermID}' ";
            }
            if (!empty($Alias)) {
                $condition .= " AND a.`Alias` = '{$Alias}' ";
            }

            if ($Bound == 1 || $Bound == 0) {
                // Owner此设备绑定人员的ID。 如果为空，表明此设备还未绑定。---- XXX
                // $Bound为bool类型
                // 对应person表的ID
                // 进行返回设备过滤。
                //只返回已绑定人员的设备，或只返回未绑定人员的设备。
                //提供不提供只参数，则不进行是否绑定过滤
                if ($Bound) {
                    // 只返回已绑定人员的设备
                    $condition .= " AND a.`Owner` <> '' ";
                } else {
                    // 只返回未绑定人员的设备
                    $condition .= " AND a.`Owner` = '' ";
                }
            }

            if ($Online == 1 || $Online == 0) {
                // Working设备的工作状态。0:未知状态/保留状态；1:在线工作中；2:离线 ---- XXX
                // $Online为bool类型
                // 进行返回设备过滤。
                //只返回当前在线的设备，或只返回离线设备。
                //提供不提供只参数，则不进行是否在线离线过滤
                if ($Online) {
                    // 只返回当前在线的设备
                    $condition .= " AND a.`Working` = 1 ";
                } else {
                    // 只返回离线设备
                    $condition .= " AND a.`Working` = 2 ";
                }
            }

            if ($Type !== -1) {
                // Type进行返回设备过滤。
                // 只返回指定类型的设备。如果不提供此参数，则不进行此类型过滤
                $condition .= " AND a.`Type` = {$Type}";
            }

            $sql0 = "SELECT COUNT(*) as num FROM device a";
            $sql1 = "SELECT a.`ID`, a.`TermID`, a.`Alias`, a.`Type`, a.`State`, a.`Working`,";
            $sql1 .= " c.`ID` AS person_ID, c.`Name` AS Name, b.`Name` AS Scene, d.`Type` AS outline_Type, d.`a`, d.`b`, a.`LastTime`";
            $sql1 .= " FROM device a LEFT JOIN scene b on a.`Scene` = b.`ID`";
            $sql1 .= " LEFT JOIN person c on a.`Owner` = c.`ID`";
            $sql1 .= " LEFT JOIN outline d on a.`Outline` = d.`ID`";
            if (!empty($condition)) {
                $sql0 .= $condition;
                $sql1 .= $condition;
            }
            $sql1 .= ' LIMIT ' . $PageIndex * $PageSize . ',' . $PageSize;
            $total = Db::connect($this->databaseInfo)->query($sql0);
            $list = Db::connect($this->databaseInfo)->query($sql1);

            // 填充输出的json结构
            // 组合数据
            $dataArray = [];
            $dataArray["total"] = $total[0]['num'];//当前返回设备的个数
            $subdataArray = [];
            foreach ($list as $item) {
                $subOwner = [];
                $subOutline = [];
                $data = [
                    'ID' => "",
                    'TermID' => "",
                    'Alias' => "",
                    'Type' => 0,
                    'State' => 0,
                    'Working' => 0,
                    'Owner' => null,  // 由c.`ID`, c.`Name` AS Name组成
                    'Scene' => "",
                    'Outline' => null,    // 由d.`Type` AS outline_ID, d.`a`, d.`b`
                    'LastTime' => "",
                ];
                $data['ID'] = $item['ID'];
                $data['TermID'] = $item['TermID'];
                $data['Alias'] = $item['Alias'];
                $data['Type'] = $item['Type'];
                $data['State'] = $item['State'];
                $data['Working'] = $item['Working'];
                // Owner的数组
                if(!empty($item['person_ID']))
                {
                    $subOwner['ID'] = $item['person_ID'];
                    $subOwner['Name'] = $item['Name'];
                    $data['Owner'] = $subOwner;     // 赋给字符数组
                }
                // Scene
                $data['Scene'] = $item['Scene'];
                // Outline的数组
                if(!empty($item['outline_Type']))
                {
                    $subOutline['Type'] = $item['outline_Type'];
                    $subOutline['a'] = $item['a'];
                    $subOutline['b'] = $item['b'];
                    $data['Outline'] = $subOutline;     // 赋给字符数组
                }
                // LastTime
                $data['LastTime'] = $item['LastTime'];
                $subdataArray[] = $data;
            }
            $dataArray['result'] = $subdataArray;
            $dataArray["PageNum"] = ceil(round((sizeof($list) / $PageSize), 1));  // 总共有几页，向上取整

            $this->success2($dataArray);
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 5.8 获取多个设备最新定位信息接口
    // http://mg.acciot.com.tw/api/V2/latest_device_position
    // http://localhost:9100/api/v2/latest_device_position
    public function latest_device_position()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'POST') {
            $ID = array();
            if (isset($this->decodedata['ID'])) {
                $ID = $this->decodedata['ID'];
            }
            if (!is_array($ID)) {
                $this->error2('The parameter ID must be a array!', 400);
            }
            // 组合条件
            $ID = array_filter($ID);
            $ID_List = [];  # 保存deviceID列表或TermID转换后的deviceID
            if (sizeof($ID) > 0) {
                for($x = 0; $x < count($ID); $x++)
                {
                    $ID_List[] = $ID[$x];
                }
            }
            else {
                $TermID = array();
                if (isset($this->decodedata['TermID'])) {
                    $TermID = $this->decodedata['TermID'];
                }
                if (!is_array($TermID)) {
                    $this->error2('The parameter TermID must be a array', 400);
                }
                $TermID = array_filter($TermID);
                if (sizeof($TermID) > 0) {
                    // 设备的TermID，这两个参数，只需要提供一个。
                    // 以ID参数优先。即在有ID参数的情况下，忽略TermID参数
                    foreach ($TermID as $item)
                    {
                        if(!is_string($item))
                            $this->error2('TermID should be string array!', 400);
                    }
                    $strTermID = join("','", $TermID);
                    // 先对应ID，然后统一在position表里按"device"查询最新位置
                    $sql = "SELECT `ID` FROM device WHERE `TermID` IN ('{$strTermID}') ";
                    $deviceIDlist = Db::connect($this->databaseInfo)->query($sql);
                    foreach ($deviceIDlist as $item) {
                        $ID_List[] = $item['ID'];
                    }
                }
                else
                {
                    $this->error2("Parameter ID or TermID must have one！", 400);
                }
            }
            // 填充输出的json结构
            // 组合数据
            $dataArray = [];
            $dataArray["total"] = 0;//当前返回设备的个数
            $subdataArray = [];
            foreach($ID_List as $item)
            {
                $sql = "select b.`ID` as deviceID, b.`TermID`, b.`Type`, a.* ";
                $sql .= " FROM position a INNER JOIN device b  ON a.`Device` = b.`ID` ";
                $sql .= " WHERE a.`device` = '{$item}' order by a.`RecordTime` desc limit 1";
                $list = Db::connect($this->databaseInfo)->query($sql);
                foreach($list as $item)
                {
                    // 只有一条
                    $dataArray['total'] ++;
                    // 组合subdataArray
                    if ($item['Battery'] < 0) {
                        // 没有电池电量
                        $data = [
                            'time' => 0,
                            'ID' => "",
                            'TermID' => "",
                            'Type' => 0,
                            'lon' => 0.0,
                            'lat' => 0.0,
                            'alt' => 0.0,
                            'dir' => 0.0,
                            'vel' => 0.0,
                            'height' => 0,
                            'status' => 0
                        ];
                        // 日期转换为时间戳
                        $data['time'] = strtotime($item['RecordTime']);
                        $data['ID'] = $item['deviceID'];
                        $data['TermID'] = $item['TermID'];
                        $data['Type'] = $item['Type'];
                        $data['lon'] = $item['lon'];
                        $data['lat'] = $item['lat'];
                        $data['alt'] = $item['alt'];
                        $data['dir'] = $item['dir'];
                        $data['vel'] = $item['vel'];
                        $data['height'] = $item['height'];
                        $data['status'] = $item['status'];
                        break;
                    } else {
                        // 有电池电量
                        $data = [
                            'time' => 0,
                            'ID' => "",
                            'TermID' => "",
                            'Type' => 0,
                            'lon' => 0.0,
                            'lat' => 0.0,
                            'alt' => 0.0,
                            'dir' => 0.0,
                            'vel' => 0.0,
                            'Battery' => 0.0,
                            'height' => 0,
                            'status' => 0
                        ];
                        // 日期转换为时间戳
                        $data['time'] = strtotime($item['RecordTime']);
                        $data['ID'] = $item['deviceID'];
                        $data['TermID'] = $item['TermID'];
                        $data['Type'] = $item['Type'];
                        $data['lon'] = $item['lon'];
                        $data['lat'] = $item['lat'];
                        $data['alt'] = $item['alt'];
                        $data['dir'] = $item['dir'];
                        $data['vel'] = $item['vel'];
                        $data['Battery'] = $item['Battery'];
                        $data['height'] = $item['height'];
                        $data['status'] = $item['status'];
                    }
                    // 统一赋值
                    $subdataArray[] = $data;
                    break;
                }
            }
            $dataArray['result'] = $subdataArray;
            // 输出
            $this->success2($dataArray);
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 5.9 获取设备历史定位信息接口
    //http://rhc.test/api/v2/history_device_position
    //http://106.15.192.73:9090/api/v2/history_device_position
    public function history_device_position()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        }
        else if ($method == 'POST') {
            $ID = "";
            if (isset($this->decodedata['ID'])) {
                $ID = $this->decodedata['ID'];
            }
            if(!is_string($ID))
            {
                $this->error2("The parameter ID must be a string!", 400);
            }
            if(!empty($ID))
            {
                $condition = " a.`ID` = '{$ID}'";
            }

            $TermID = "";
            if (isset($this->decodedata['TermID'])) {
                $TermID = $this->decodedata['TermID'];
            }
            if(!is_string($TermID))
            {
                $this->error2("The parameter TermID must be a string!", 400);
            }
            if(empty($ID) && empty($TermID))
            {
                $this->error2("The parameter ID and TermID must have one!", 400);
            }
            if(empty($ID) && !empty($TermID))
            {
                $condition = " a.`TermID` = '{$TermID}'";
            }

            $StartTime = -1;
            if (isset($this->decodedata['StartTime'])) {
                $StartTime = $this->decodedata['StartTime'];
            }
            if($StartTime === -1)
            {
                $this->error2("The parameter StartTime cannot be null!", 400);
            }
            if(!is_integer($StartTime))
            {
                $this->error2("The parameter StartTime must be a integer!", 400);
            }
            if($StartTime < 0)
            {
                $this->error2("The parameter StartTime cannot less than zero!", 400);
            }
            // EndTime
            $EndTime = -1;
            if (isset($this->decodedata['EndTime']))
            {
                $EndTime = $this->decodedata['EndTime'];
            }
            if($EndTime === -1)
            {
                $this->error2("The parameter EndTime cannot be null!", 400);
            }
            if(!is_integer($EndTime))
            {
                $this->error2("The parameter EndTime must be a integer!", 400);
            }
            if($EndTime < 0)
            {
                $this->error2("The parameter EndTime cannot less than zero!", 400);
            }
            if($StartTime > $EndTime)
            {
                $this->error2("The parameter EndTime must larger than StartTime!", 400);
            }
            // 组合sql语句，查询
            // timestamp转date日期字符串
            $strstartdate = date('Y-m-d H:m:s', $StartTime);
            $strenddate = date('Y-m-d H:m:s', $EndTime);
            // sql0
            $sql0 = "SELECT COUNT(*) as num FROM device a LEFT JOIN position b ON a.`ID` = b.`Device`";
            $sql0 .= " WHERE b.`RecordTime` >= '{$strstartdate}' AND b.`RecordTime` <= '{$strenddate}'";
            $sql0 .= " AND " . $condition;
            // sql1
            $sql1 = "SELECT a.`ID` as deviceID, a.`TermID`, a.`Type`, b.*";
            $sql1 .= " FROM device a LEFT JOIN position b ON a.`ID` = b.`Device` ";
            $sql1 .= " WHERE b.`RecordTime` >= '{$strstartdate}' AND b.`RecordTime` <= '{$strenddate}'";
            $sql1 .= " AND " . $condition;
            $total = Db::connect($this->databaseInfo)->query($sql0);
            $list = Db::connect($this->databaseInfo)->query($sql1);

            // 填充输出的json结构
            $dataArray = [];
            if(empty($ID))
            {
                if(sizeof($list) > 0)
                    $dataArray["ID"] = $list[0]['deviceID'];
                $dataArray["TermID"] = $TermID;
            }
            else{
                $dataArray["ID"] = $ID;
                if(!empty($TermID))
                    $dataArray["TermID"] = $TermID;
                else if(sizeof($list) > 0)
                    $dataArray["TermID"] = $list[0]['TermID'];
            }
            $dataArray["Type"] = $list[0]["Type"];
            $dataArray["total"] = $total[0]['num'];//当前返回设备的个数
            // 组合数据
            if($dataArray["total"] > 0)
            {
                $subdataArray = [];
                foreach ($list as $item) {
                    if ($item['Battery'] < 0) {
                        // 没有电池电量
                        $data = [
                            'time' => 0,
                            'lon' => 0.0,
                            'lat' => 0.0,
                            'alt' => 0.0,
                            'dir' => 0.0,
                            'vel' => 0.0,
                            'height' => 0,
                            'status' => 0
                        ];
                        // 日期转换为时间戳
                        $data['time'] = strtotime($item['RecordTime']);
                        $data['lon'] = $item['lon'];
                        $data['lat'] = $item['lat'];
                        $data['alt'] = $item['alt'];
                        $data['dir'] = $item['dir'];
                        $data['vel'] = $item['vel'];
                        $data['height'] = $item['height'];
                        $data['status'] = $item['status'];
                    } else {
                        // 有电池电量
                        $data = [
                            'time' => 0,
                            'lon' => 0.0,
                            'lat' => 0.0,
                            'alt' => 0.0,
                            'dir' => 0.0,
                            'vel' => 0.0,
                            'Battery' => 0.0,
                            'height' => 0,
                            'status' => 0
                        ];
                        // 日期转换为时间戳
                        $data['time'] = strtotime($item['RecordTime']);
                        $data['lon'] = $item['lon'];
                        $data['lat'] = $item['lat'];
                        $data['alt'] = $item['alt'];
                        $data['dir'] = $item['dir'];
                        $data['vel'] = $item['vel'];
                        $data['Battery'] = $item['Battery'];
                        $data['height'] = $item['height'];
                        $data['status'] = $item['status'];
                    }
                    // 统一赋值
                    $subdataArray[] = $data;
                }
                $dataArray['result'] = $subdataArray;
                // 输出
                $this->success2($dataArray);
            }
            else
            {
                // 没有内容
                // 没有结果
                $dataArray["total"] = 0;//当前返回设备的个数
                $dataArray["result"] = [];
                // 输出
                $this->success2($dataArray);
            }
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 5.10 获取多个设备报警接口
    //http://rhc.test/api/v2/alarm
    //http://106.15.192.73:9090/api/v2/alarm
    public function alarm()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        }
        else if ($method == 'POST' || $method == 'GET') {
            $StartTime = -1;
            if (isset($this->decodedata['StartTime'])) {
                $StartTime = $this->decodedata['StartTime'];
            }
            if($StartTime === -1)
            {
                $this->error2("The parameter StartTime cannot be null!", 400);
            }
            if(!is_integer($StartTime))
            {
                $this->error2("The parameter StartTime must be a integer!", 400);
            }
            if($StartTime < 0)
            {
                $this->error2("The parameter StartTime cannot less than zero!", 400);
            }
            // EndTime
            $EndTime = -1;
            if (isset($this->decodedata['EndTime']))
            {
                $EndTime = $this->decodedata['EndTime'];
            }
            if($EndTime === -1)
            {
                $this->error2("The parameter EndTime cannot be null!", 400);
            }
            if(!is_integer($EndTime))
            {
                $this->error2("The parameter EndTime must be a integer!", 400);
            }
            if($EndTime < 0)
            {
                $this->error2("The parameter EndTime cannot less than zero!", 400);
            }
            if($StartTime > $EndTime)
            {
                $this->error2("The parameter EndTime must larger than StartTime!", 400);
            }

            $ID = array();
            if (isset($this->decodedata['ID'])) {
                $ID = $this->decodedata['ID'];
            }
            if (!is_array($ID)) {
                $this->error2('The parameter ID must be a array!', 400);
            }
            // 组合条件
            $ID = array_filter($ID);
            if (sizeof($ID) > 0) {
                foreach ($ID as $item)
                {
                    if(!is_string($item))
                        $this->error2('ID should be string array!', 400);
                }
                $strID = join("','", $ID);
                $condition = " a.`ID` in ('{$strID}')";
            }
            else {
                $TermID = array();
                if (isset($this->decodedata['TermID'])) {
                    $TermID = $this->decodedata['TermID'];
                }
                if (!is_array($TermID)) {
                    $this->error2('The parameter TermID must be a array', 400);
                }
                $TermID = array_filter($TermID);
                if (sizeof($TermID) > 0) {
                    // 设备的TermID，这两个参数，只需要提供一个。
                    // 以ID参数优先。即在有ID参数的情况下，忽略TermID参数
                    foreach ($TermID as $item)
                    {
                        if(!is_string($item))
                            $this->error2('TermID should be string array!', 400);
                    }
                    $strTermID = join("','", $TermID);
                    $condition = " a.`TermID` in ('{$strTermID}')";
                }
                else
                {
                    $this->error2("Parameter ID or TermID must have one！", 400);
                }
            }
            // 组合sql语句，查询
            $sql0 = "SELECT COUNT(*) as num FROM device a LEFT JOIN warning b ON a.`ID` = b.`Device`";
            $sql0 .= " WHERE UNIX_TIMESTAMP(b.`RecordTime`) >= {$StartTime} AND UNIX_TIMESTAMP(b.`RecordTime`) <= {$EndTime}";
            $sql0 .= " AND " . $condition;
            $sql1 = "SELECT a.`ID`, a.`TermID`, a.`Type`, b.`RecordTime`,b.`Type` as Warning ";
            $sql1 .= " FROM device a LEFT JOIN warning b ON a.`ID` = b.`Device` ";
            $sql1 .= " WHERE UNIX_TIMESTAMP(b.`RecordTime`) >= {$StartTime} AND UNIX_TIMESTAMP(b.`RecordTime`) <= {$EndTime}";
            $sql1 .= " AND " . $condition;

            $total = Db::connect($this->databaseInfo)->query($sql0);
            // 填充输出的json结构
            // 组合数据
            $dataArray = [];
            $dataArray["total"] = $total[0]['num'];//当前返回设备的个数
            if($dataArray["total"] > 0)
            {
                $list = Db::connect($this->databaseInfo)->query($sql1);
                $dataArray["total"] = $total[0]['num'];//当前返回设备的个数
                $subdataArray = [];

                foreach ($list as $item) {
                    // 日期转换为时间戳
                    $data['time'] = strtotime($item['RecordTime']);
                    $data['ID'] = $item['ID'];
                    $data['TermID'] = $item['TermID'];
                    $data['Type'] = $item['Type'];
                    $data['Warning'] = $item['Warning'];
                    // 统一赋值
                    $subdataArray[] = $data;
                }
                $dataArray['result'] = $subdataArray;
            }
            else
            {
                // 没有内容
                // 没有结果
                $dataArray["total"] = 0;//当前返回设备的个数
                $dataArray["result"] = [];
            }
            // 输出
            $this->success2($dataArray);
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 5.11 向多个设备发送TTS文本接口
    //http://rhc.test/api/v2/tts
    //http://106.15.192.73:9090/api/v2/tts
    public function tts()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        }
        else if ($method == 'POST') {
            $ID = array();
            if (isset($this->decodedata['ID'])) {
                $ID = $this->decodedata['ID'];
            }
            if (!is_array($ID)) {
                $this->error2('The parameter ID must be a array!', 400);
            }
            // 组合条件
            $ID = array_filter($ID);
            if (sizeof($ID) > 0) {
                foreach ($ID as $item)
                {
                    if(!is_string($item))
                        $this->error2('ID should be string array!', 400);
                }
                $strID = join("','", $ID);
                $condition = " `ID` in ('{$strID}')";
            }
            else {
                $TermID = array();
                if (isset($this->decodedata['TermID'])) {
                    $TermID = $this->decodedata['TermID'];
                }
                if (!is_array($TermID)) {
                    $this->error2('The parameter TermID must be a array', 400);
                }
                $TermID = array_filter($TermID);
                if (sizeof($TermID) > 0) {
                    // 设备的TermID，这两个参数，只需要提供一个。
                    // 以ID参数优先。即在有ID参数的情况下，忽略TermID参数
                    foreach ($TermID as $item)
                    {
                        if(!is_string($item))
                            $this->error2('TermID should be string array!', 400);
                    }
                    $strTermID = join("','", $TermID);
                    $condition = " `TermID` in ('{$strTermID}')";
                }
                else
                {
                    $this->error2("Parameter ID or TermID must have one！", 400);
                }
            }
            // message
            $message = null;
            if (isset($this->decodedata['message'])) {
                $message = $this->decodedata['message'];
            }
            if(!empty($message) && !is_string($message))
            {
                $this->error2("The parameter message must be a string!", 400);
            }
            if(empty($message))
            {
                $this->error2("The parameter message cannot be null!", 400);
            }
            // 向设备发送TTS文本时，需要确认此设备类型支持接收TTS文本，目前只有安全帽(device:Type=>1)和安全绳(3)支持，否则发送不成功
            // 必须确认设备在线(device: Working=>1:在线工作中)，否则发送不成功
            // 如果所有的设备都发送不成功，则函数执行失败
            // 只要有一个设备发送成功， 则函数执行成功
            // 数据库连接
            $connect=mysqli_connect($this->decodedata['ip'],$this->decodedata['username'],$this->databaseInfo['password'],$this->decodedata['scheme']);
            if (mysqli_connect_errno($connect))
            {
                $this->error2("Connect MySQL Fail, " . mysqli_connect_error(), 400);
            }

            // 先判断ID和TermID是否存在？
            $sql = "SELECT COUNT(*) as num FROM device WHERE `Type` IN (1,3) AND `Working` = 1 AND " . $condition;
            $total = Db::connect($this->databaseInfo)->query($sql);
            if($total[0]['num'] <= 0)
            {
                $this->error2('No device can meet the condition!', 400);
            }
            // 成功，写LOG
            // 插入到logue表中
            $url = $this->GetCurUrl();
            $this->InsertLogue($url, json_encode($this->decodedata), 200, "");
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 5.12 获取所有设备状态统计接口
    //获取当前平台中，所有设备的总数，在线设备个数
    //http://rhc.test/api/v2/device_summary
    public function device_summary()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        }
        else if ($method == 'POST') {
            $Type = array();
            if (isset($this->decodedata['Type'])) {
                $Type = $this->decodedata['Type'];
            }
            if (!is_array($Type)) {
                $this->error2('The parameter Type must be a array!', 400);
            }

            if (sizeof($Type) > 0)
            {
                foreach ($Type as $item)
                {
                    if(!is_integer($item))
                    {
                        $this->error2('The parameter Type must be a interger array!', 400);
                    }
                }
            }
            // 组合条件
            $condition = " WHERE 1 ";
            $Type = array_filter($Type);
            if (count($Type) > 0) {
                $strType = join(",", $Type);
                $condition .= " AND `Type` in ({$strType})";
            }
            // 组合sql语句，查询
            $sql0 = "SELECT COUNT(*) as num FROM device ";
            if (!empty($condition)) {
                $sql0 .= $condition;
            }
            $sql1 = $sql0 . " AND Working = 1";
            $total = Db::connect($this->databaseInfo)->query($sql0);
            $online = Db::connect($this->databaseInfo)->query($sql1);

            $data = [];
            $data["total"] = $total[0]['num'];
            $data["online"] = $online[0]['num'];
            $this->success2($data);
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    //6.1 添加静态电子围栏接口
    //http://rhc.test/api/v2/add_static_fence
    public function add_static_fence()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        }
        else if ($method == 'POST') {
            try
            {
                // Name
                $Name = "";
                if (isset($this->decodedata['Name'])) {
                    $Name = $this->decodedata['Name'];
                }
                if(!empty($Name) && !is_string($Name)) {
                    $this->error2("The parameter Name must be a string!", 400);
                }
                if(empty($Name)) {
                    $this->error2("The parameter Name cannot be null!", 400);
                }
                // 提供的名称已存在，则添加不成功
                $sql = "SELECT COUNT(*) AS num FROM fence WHERE `Name` = '{$Name}'";
                $list = Db::connect($this->databaseInfo)->query($sql);
                $num = intval($list[0]['num']);
                if($num > 0)
                {
                    $this->error2("The Name of fence already exists!", 400);
                }
                // Rule bool类型
                $Rule = 1;
                if (isset($this->decodedata['Rule'])) {
                    $Rule = $this->decodedata['Rule'];
                }
                if($Rule != 1)
                {
                    if(!is_bool($Rule))
                        $this->error2("The parameter Rule should be a bool!", 400);
                    $Rule = 0;
                }
                // StartTime
                $StartTime = "00:00:00";
                if (isset($this->decodedata['StartTime'])) {
                    $StartTime = $this->decodedata['StartTime'];
                }
                if($StartTime != "00:00:00")
                {
                    if(!is_string($StartTime))
                        $this->error2("The parameter StartTime must be a string!", 400);
                    if( strtotime($StartTime) <= 0 or strlen($StartTime) > 9)
                        $this->error2("The parameter StartTime must be 'HH:MM:SS' format!", 400);
                }
                // EndTime
                $EndTime = "23:59:59";
                if (isset($this->decodedata['EndTime']))
                {
                    $EndTime = $this->decodedata['EndTime'];
                }
                if($EndTime != "23:59:59")
                {
                    if(!is_string($EndTime))
                        $this->error2("The parameter EndTime must be a string!", 400);
                    if( strtotime($EndTime) <= 0 or strlen($EndTime) > 9)
                        $this->error2("The parameter EndTime must be 'HH:MM:SS' format!", 400);
                }
                // 如果EndTime的时间早于StartTime，需要交换
                if($EndTime < $StartTime)
                {
                    $tempTime = $StartTime;
                    $StartTime = $EndTime;
                    $EndTime = $tempTime;
                }
                // Height
                $Height = 0.0;
                if (isset($this->decodedata['Height'])) {
                    $Height = $this->decodedata['Height'];
                }
                if( $Height !== 0.0 && ( !is_float($Height) && !is_integer($Height) ) ) 
                    $this->error2("The Height must be a number!", 400);
                // PtType bool类型
                $PtType = 1;
                if (isset($this->decodedata['PtType'])) {
                    $PtType = $this->decodedata['PtType'];
                }
                if($PtType != 1)
                {
                    if(!is_bool($PtType)) $this->error2("The parameter PtType should be a bool!", 400);
                    $PtType = 0;
                }
                // points
                $point_input = array();
                if (isset($this->decodedata['point'])) {
                    $point_input = $this->decodedata['point'];
                }
                if(empty($point_input))
                {
                    $this->error2("The parameter point cannot be null!", 400);
                }
                if (!is_array($point_input)) {
                    $this->error2('The parameter point must be a array!', 400);
                }
                // 组合条件
                $point_input = array_filter($point_input);
                // 组合成格式：$point = [ [121.456, 31.5678],[121.568,31.9654] ];
                $point = [];
                foreach ($point_input as $item)
                {
                    // 检查是否有重复对？
                    foreach ($point as $onepoint)
                    {
                        if($item['lon'] == $onepoint[0] && $item['lat'] == $onepoint[1])
                        {
                            $this->error2("The point array has duplicate values! it's lon:{$item['lon']},lat:{$item['lat']}", 400);
                        }
                    }
                    if(!is_float($item['lon']) || !is_float($item['lat']))
                    {
                        $this->error2("The point array must be a double type", 400);
                    }
                    if( !$this->isChinaLonLat($item['lon'], $item['lat']) )
                    {
                        $this->error2("The LonLat({$item['lon']}, {$item['lat']}) is out of range of china!", 400);
                    }
                    $point[] = [(double)$item['lon'], (double)$item['lat']];
                }
                $ptNums = sizeof($point);
                // 2）如果提供的多边形顶点的个数小于3， 添加不成功
                if($ptNums < 3)
                {
                    $this->error2("The number of point cannot less than 3!", 400);
                }
                $point_binpack = "";
                for($i = 0; $i < count($point); $i++)
                {
                    $lon1 = pack("d*", $point[$i][0]);
                    $lat1 = pack("d*", $point[$i][1]);
                    $point_binpack .= $lon1 . $lat1;
                }
                $Points = unpack("d*", $point_binpack);
                // echo json_encode($Points);

                $ID = $this->create_guid();
                $RecordTime = date('Y-m-d H:i:s');
                // 存入blob字段一定要用以下方式bind
                $sql = "INSERT INTO fence(`ID`, `Source`, `Name`, `Rule`, `StartTime`, `EndTime`, `PtNum`, `Points`, `PtType`, `Height`, `RecordTime`) ";
                $sql .= " VALUES ('{$ID}', '1', '{$Name}', {$Rule}, '{$StartTime}', '{$EndTime}', {$ptNums}, :a, {$PtType}, {$Height}, '{$RecordTime}')";
                $bind = [
                    'a' => $point_binpack,
                ];
                Db::connect($this->databaseInfo)->query($sql, $bind);

                $data = [];
                $data["ID"] = $ID;
                $this->success2($data);
            }
            catch (HttpException $e) {
                //时刻准备着，处理上面抛出的HTTP问题
                $this->error2("Data processing error! please try again!", 400);
            } catch (Exception $e) {
                //时刻准备着，处理他们都处理不了的问题
                $this->error2("Data processing error! please try again!", 400);
            } finally {
                //打扫战场，都收拾好了再走人
                // $this->error2("Data processing error! please try again!", 400);
            }
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    //6.2 添加动态电子围栏接口
    //http://rhc.test/api/v2/add_dynamic_fence
    public function add_dynamic_fence()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        }
        else if ($method == 'POST') {
            // Name
            $Name = "";
            if (isset($this->decodedata['Name'])) {
                $Name = $this->decodedata['Name'];
            }
            if(!empty($Name) && !is_string($Name)) {
                $this->error2("The parameter Name must be a string!", 400);
            }
            if(empty($Name)) {
                $this->error2("The parameter Name cannot be null!", 400);
            }
            // 提供的名称已存在，则添加不成功
            $sql = "SELECT COUNT(*) AS num FROM fence WHERE `Name` = '{$Name}'";
            $list = Db::connect($this->databaseInfo)->query($sql);
            $num = intval($list[0]['num']);
            if($num > 0)
            {
                $this->error2("The Name of fence already exists!", 400);
            }

            // Rule bool类型
            $Rule = 1;
            if (isset($this->decodedata['Rule'])) {
                $Rule = $this->decodedata['Rule'];
            }
            if($Rule != 1)
            {
                if(!is_bool($Rule))
                    $this->error2("The parameter Rule should be a bool!", 400);
                $Rule = 0;
            }

            // StartTime
            $StartTime = "00:00:00";
            if (isset($this->decodedata['StartTime'])) {
                $StartTime = $this->decodedata['StartTime'];
            }
            if($StartTime != "00:00:00")
            {
                if(!is_string($StartTime))
                    $this->error2("The parameter StartTime must be a string!", 400);
                if( strtotime($StartTime) <= 0 or strlen($StartTime) > 9)
                    $this->error2("The parameter StartTime must be 'HH:MM:SS' format!", 400);
            }

            // EndTime
            $EndTime = "23:59:59";
            if (isset($this->decodedata['EndTime']))
            {
                $EndTime = $this->decodedata['EndTime'];
            }
            if($EndTime != "23:59:59")
            {
                if(!is_string($EndTime))
                    $this->error2("The parameter EndTime must be a string!", 400);
                if( strtotime($EndTime) <= 0 or strlen($EndTime) > 9)
                    $this->error2("The parameter EndTime must be 'HH:MM:SS' format!", 400);
            }
            // 如果EndTime的时间早于StartTime，需要交换
            if($EndTime < $StartTime)
            {
                $tempTime = $StartTime;
                $StartTime = $EndTime;
                $EndTime = $tempTime;
            }

            // Height
            $Height = -9999.0;
            if (isset($this->decodedata['Height'])) {
                $Height = $this->decodedata['Height'];
            }
            if( $Height != -9999.0 && (!is_double($Height) && !is_integer($Height)) ) 
                $this->error2("The Height must be a number!", 400);

            // DeviceID
            $condition = " 1 AND ";
            $DeviceID = array();
            if (isset($this->decodedata['DeviceID'])) {
                $DeviceID = $this->decodedata['DeviceID'];
            }
            if (!is_array($DeviceID)) {
                $this->error2('DeviceID should be array', 400);
            }
            $DeviceID = array_filter($DeviceID);
            if (sizeof($DeviceID) > 0) {
                foreach ($DeviceID as $item)
                {
                    if(!is_string($item))
                        $this->error2('DeviceID should be string array!', 400);
                }
                $strDeviceID = join("','", $DeviceID);
                $condition .= " `ID` in ('{$strDeviceID}')";
                // 判断是不是存在，如果都不存在，就添加不成功
                $sql = "SELECT `ID` FROM device WHERE {$condition}";
                $list = Db::connect($this->databaseInfo)->query($sql);
                $num = count($list);
                if($num <= 0)
                {
                    $this->error2("The deviceID doesn't exist! add failed!", 400);
                }
                $DeviceID = $list;
            }
            else
            {
                // 判断TermID
                $TermID = array();
                if (isset($this->decodedata['TermID'])) {
                    $TermID = $this->decodedata['TermID'];
                }
                if (!is_array($TermID)) {
                    $this->error2('TermID should be array', 400);
                }
                if (sizeof($TermID) > 0) {
                    foreach ($TermID as $item)
                    {
                        if(!is_string($item))
                            $this->error2('TermID should be string array!', 400);
                    }
                    $strTermID = join("','", $TermID);
                    $condition .= " `TermID` in ('{$strTermID}')";

                    // 判断是不是存在，如果都不存在，就添加不成功
                    $sql = "SELECT ID FROM device WHERE {$condition}";
                    $list = Db::connect($this->databaseInfo)->query($sql);
                    $num = count($list);
                    if($num <= 0)
                    {
                        $this->error2("The TermID doesn't exist! add failed!", 400);
                    }
                    // 将TermID对应deviceID
                    $DeviceID = $list;
                }
                else
                {
                    $this->error2("The DeviceID and TermID cannot both be empty!", 400); 
                }
            }
            // 数据库连接
            $connect=mysqli_connect($this->decodedata['ip'],$this->decodedata['username'],$this->databaseInfo['password'],$this->decodedata['scheme']);
            if (mysqli_connect_errno($connect))
            {
                $this->error2('Connect MySQL Fail, ' . mysqli_connect_error(), 400);
            }

            // Outline是object
            $Outline = [];
            if (isset($this->decodedata['Outline'])) {
                $Outline = $this->decodedata['Outline'];
            }
            if(!is_array($Outline))
            {
                $this->error2("The parameter Outline must be a object!", 400);
            }
            if(sizeof($Outline) == 0)
            {
                $this->error2("The Outline doesn't be null!", 400);
            }
            // Type一定要存在
            if(empty($Outline['Type']))
            {
                $this->error2("The parameter Type of Outline cannot be null!!", 400);
            }

            // 判断Outline里的参数Type,a,b,c
            // 0， 1， 2， 3 <---->1 device;    4 <-----> 2 devices;     5<------> 3 or more devices
            if($Outline['Type'] != 2 && $Outline['Type'] != 3 && $Outline['Type'] != 4 && $Outline['Type'] != 5)
            {
                $this->error2("The parameter Type of Outline can only be 2,3,4 or 5!", 400);
            }
            else
            {
                if($Outline['Type'] == 2)   // 圆
                {
                    // 必须有a
                    if(empty($Outline['a']))
                    {
                        $this->error2("The parameter a of Outline must be exist when Type is 2!", 400);
                    }
                    if($Outline['a'] <= 0)
                    {
                        $this->error2("The parameter a of Outline must be larger than zero when Type is 2!", 400);
                    }
                    //要检查设备的个数是否与轮廓外形所需的设备数目一致，圆只需要1个设备
                    if(count($DeviceID) != 1)
                    {
                        $this->error2("The number of devices does not meet the needs when type is 2!", 400);
                    }
                    // 判断该outline是否存在，如果不存在，就要添加
                    $sql = "SELECT `ID` FROM outline WHERE `Type`={$Outline['Type']} AND `a`={$Outline['a']}";
                    $list = Db::connect($this->databaseInfo)->query($sql);
                    if(count($list) <= 0)
                    {
                        // 不存在
                        $ID = $this->create_guid();
                        $CreateTime = date('Y-m-d H:i:s');
                        $sql = "INSERT INTO outline(`ID`, `Type`, `a`, `CreateTime`) ";
                        $sql .= " VALUES ('{$ID}', {$Outline['Type']}, {$Outline['a']}, '{$CreateTime}')";
                        $result = mysqli_query($connect, $sql);
                        if(mysqli_affected_rows($connect) <= 0)
                        {
                            mysqli_close($connect);
                            $this->error2("Add Outline failed!", 400);
                        }
                        $OutlineID = $ID;
                    }
                    else
                        $OutlineID = $list[0]['ID'];
                }
                elseif($Outline['Type'] == 3)   // 单点矩形
                {
                    // 必须有a和b
                    if(empty($Outline['a']) or empty($Outline['b']))
                    {
                        $this->error2("The parameter a and b of Outline must be exist when Type is 3!", 400);
                    }
                    if($Outline['a'] > $Outline['b'])
                    {
                        $this->error2("The parameter a of Outline must be less than or equal to parameter b when Type is 3!", 400);
                    }
                    if($Outline['a'] <= 0)
                    {
                        $this->error2("The parameter a of Outline must be larger than zero when Type is 3!", 400);
                    }
                    if($Outline['b'] <= 0)
                    {
                        $this->error2("The parameter b of Outline must be larger than zero when Type is 3!", 400);
                    }
                    //要检查设备的个数是否与轮廓外形所需的设备数目一致，矩形至少需要2个设备
                    if(count($DeviceID) != 1)
                    {
                        $this->error2("The number of devices does not meet the needs when type is 3!", 400);
                    }
                    // 判断该outline是否存在，如果不存在，就要添加
                    $sql = "SELECT `ID` FROM outline WHERE `Type`={$Outline['Type']} AND `a`={$Outline['a']} AND `b`={$Outline['b']}";
                    $list = Db::connect($this->databaseInfo)->query($sql);
                    if(count($list) <= 0)
                    {
                        // 不存在
                        $ID = $this->create_guid();
                        $CreateTime = date('Y-m-d H:i:s');
                        $sql = "INSERT INTO outline(`ID`, `Type`, `a`, `b`, `CreateTime`) ";
                        $sql .= " VALUES ('{$ID}', {$Outline['Type']}, {$Outline['a']}, {$Outline['b']}, '{$CreateTime}')";
                        $result = mysqli_query($connect, $sql);
                        if(mysqli_affected_rows($connect) <= 0)
                        {
                            mysqli_close($connect);
                            $this->error2("Add Outline failed!", 400);
                        }
                    }
                    $OutlineID = $list[0]['ID'];
                }
                elseif($Outline['Type'] == 4)   // 双点矩形
                {
                    // 必须有a,b和c
                    if(empty($Outline['a']) or empty($Outline['b']) or empty($Outline['c']))
                    {
                        $this->error2("The parameter a,b and c of Outline must be exist when Type is 4!", 400);
                    }
                    if($Outline['a'] <= 0)
                    {
                        $this->error2("The parameter a of Outline must be larger than zero when Type is 4!", 400);
                    }
                    if($Outline['b'] <= 0)
                    {
                        $this->error2("The parameter b of Outline must be larger than zero when Type is 4!", 400);
                    }
                    if($Outline['c'] <= 0)
                    {
                        $this->error2("The parameter c of Outline must be larger than zero when Type is 4!", 400);
                    }
                    //要检查设备的个数是否与轮廓外形所需的设备数目一致，多边型至少需要3个设备
                    if(count($DeviceID) != 2)
                    {
                        $this->error2("The number of devices does not meet the needs when type is 4!", 400);
                    }
                    // 判断该outline是否存在，如果不存在，就要添加
                    $sql = "SELECT `ID` FROM outline WHERE `Type`={$Outline['Type']} ";
                    $sql .= " AND `a`={$Outline['a']} AND `b`={$Outline['b']} AND `c`={$Outline['c']}";
                    $list = Db::connect($this->databaseInfo)->query($sql);
                    if(count($list) <= 0)
                    {
                        // 不存在
                        $ID = $this->create_guid();
                        $CreateTime = date('Y-m-d H:i:s');
                        $sql = "INSERT INTO outline(`ID`, `Type`, `a`, `b`, `c`, `CreateTime`) ";
                        $sql .= " VALUES ('{$ID}', {$Outline['Type']}, {$Outline['a']}, {$Outline['b']}, {$Outline['c']}, '{$CreateTime}')";
                        $result = mysqli_query($connect, $sql);
                        if(mysqli_affected_rows($connect) <= 0)
                        {
                            mysqli_close($connect);
                            $this->error2("Add Outline failed!", 400);
                        }
                        $OutlineID = $ID;
                    }
                    else
                        $OutlineID = $list[0]['ID'];
                }
                else    // =5
                {
                    // outline为5，查询出来可能不止一个，只取第一个
                    //要检查设备的个数是否与轮廓外形所需的设备数目一致，多边型至少需要4个设备
                    if(count($DeviceID) < 2)
                    {
                        $this->error2("The number of devices does not meet the needs when type is 5!", 400);
                    }
                    // 判断该outline是否存在，如果不存在，就要添加
                    $sql = "SELECT `ID` FROM outline WHERE `Type`={$Outline['Type']} LIMIT 1";
                    $list = Db::connect($this->databaseInfo)->query($sql);
                    if(count($list) <= 0)
                    {
                        // 不存在
                        $ID = $this->create_guid();
                        $CreateTime = date('Y-m-d H:i:s');
                        $sql = "INSERT INTO outline(`ID`, `Type`, `CreateTime`)";
                        $sql .= " VALUES ('{$ID}', {$Outline['Type']}, '{$CreateTime}')";
                        $result = mysqli_query($connect, $sql);
                        if(mysqli_affected_rows($connect) <= 0)
                        {
                            mysqli_close($connect);
                            $this->error2("Add Outline failed!", 400);
                        }
                        $OutlineID = $ID;
                    }
                    else
                        $OutlineID = $list[0]['ID'];
                }
            }

            // 先插入fence的动态
            $fenceID = $this->create_guid();
            $RecordTime = date('Y-m-d H:i:s');
            $sql = "INSERT INTO fence(`ID`, `Source`, `Name`, `Rule`, `StartTime`, `EndTime`, `RecordTime`) ";
            $sql .= " VALUES ('{$fenceID}', '0', '{$Name}', {$Rule}, '{$StartTime}', '{$EndTime}', '{$RecordTime}')";
            $result_fence = mysqli_query($connect, $sql);
            if(!$result_fence)
            {
                mysqli_close($connect);
                $this->error2("Add table failed!", 400);
            }
            // 更新device表的Fence字段
            $sql = "UPDATE device SET `Fence` = '{$fenceID}' WHERE " . $condition;
            $result_update = mysqli_query($connect, $sql);
            if(!$result_update)
            {
                mysqli_close($connect);
                $this->error2("Update device failed!", 400);
            }
            // 再插入fence_device
            $ID = $this->create_guid();
            // 组合deviceID，构成此动态围栏的设备ID序列。并用逗号分隔
            $DeviceID_list = [];
            foreach($DeviceID as $item)
            {
                $DeviceID_list[] = $item["ID"];
            }
            $strDeviceID = join(",", $DeviceID_list);
            $sql = "INSERT INTO fence_device(`ID`, `Outline`, `Devices`, `Fence`, `Height`, `CreateTime`) ";
            $sql .= " VALUES ('{$ID}', '{$OutlineID}', '{$strDeviceID}', '{$fenceID}', {$Height}, '{$RecordTime}')";
            $result_insert = mysqli_query($connect, $sql);
            if(!$result_insert)
            {
                mysqli_close($connect);
                $this->error2("Add table failed!", 400);
            }

            $data = [];
            $data["ID"] = $fenceID;
            $this->success2($data);
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 6.3 删除电子围栏接口
    //http://rhc.test/api/v2/delete_device
    public function delete_fence()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        }
        else if ($method == 'POST') {
            // 围栏的ID
            $ID = "";
            if (isset($this->decodedata['ID'])) {
                $ID = $this->decodedata['ID'];
            }
            if(!is_string($ID))
            {
                $this->error2("The parameter ID must be a string!", 400);
            }
            
            // 数据库连接
            $connect=mysqli_connect($this->decodedata['ip'],$this->decodedata['username'],$this->databaseInfo['password'],$this->decodedata['scheme']);
            if (mysqli_connect_errno($connect))
            {
                $this->error2('Connect MySQL Fail, ' . mysqli_connect_error(), 400);
            }

            if(empty($ID))
            {
                // 围栏的名称
                $Name = "";
                if (isset($this->decodedata['Name'])) {
                    $Name = $this->decodedata['Name'];
                }
                if(!is_string($Name))
                {
                    $this->error2("The parameter Name must be a string!", 400);
                }
                if(empty($Name))
                {
                    $this->error2("The ID and Name cannot both be empty!", 400);
                }
                // 由Name取出ID，便于后面的统一查询处理
                $sql = "SELECT `ID` FROM fence WHERE `Name` = '{$Name}'";
                $result = mysqli_query($connect, $sql);
                while ($row = mysqli_fetch_assoc($result)) {
                    $ID = $row["ID"];
                }
            }
            // 1、先判断是不是动态fence，如果删除的围栏是动态围栏， 则fence_device表的对应记录要一起删除
            $sql = "SELECT `Source` FROM fence WHERE `ID` = '{$ID}'";
            $result = mysqli_query($connect, $sql);
            // 先删除动态fence_device
            while ($row = mysqli_fetch_assoc($result)) 
            {
                if($row['Source'] == '0')   // 是动态fence
                {
                    $sql_delete = "DELETE FROM fence_device WHERE `Fence` = '{$ID}'";
                    $result_delete = mysqli_query($connect, $sql_delete);
                }
            }
            // 2、再清空device里的fence字段
            $sql_update = "UPDATE device SET `Fence` = '' WHERE `Fence` = '{$ID}'";
            $result_update = Db::connect($this->databaseInfo)->query($sql_update);
            // 3、最后删除fence里的记录
            $sql_del = "DELETE FROM fence WHERE `ID` = '{$ID}'";
            $result_del = Db::connect($this->databaseInfo)->query($sql_del);
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    // 6.4 电子围栏列表接口
    //http://rhc.test/api/v2/list_fence
    public function list_fence()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        }
        else if ($method == 'POST') {
            // Source bool类型
            $condition = " WHERE 1 ";
            $Source = -1;
            if (isset($this->decodedata['Source'])) {
                $Source = $this->decodedata['Source'];
            }
            if($Source !== -1)
            {
                if(!is_bool($Source))
                    $this->error2("The parameter Source should be a bool!", 400);
                if($Source != 1) $Source = 0;
                $condition .= " AND `Source`='{$Source}'";
            }

            // Rule bool类型
            $Rule = -1;
            if (isset($this->decodedata['Rule'])) {
                $Rule = $this->decodedata['Rule'];
            }
            if($Rule !== -1)
            {
                if(!is_bool($Rule))
                    $this->error2("The parameter Rule should be a bool!", 400);
                if($Rule != 1) $Rule = 0;
                $condition .= " AND `Rule`={$Rule}";
            }
            
            // Valid bool类型
            $Valid = -1;
            if (isset($this->decodedata['Valid'])) {
                $Valid = $this->decodedata['Valid'];
            }
            if($Valid !== -1)
            {
                if(!is_bool($Valid))
                    $this->error2("The parameter Valid should be a bool!", 400);
                if($Valid != 1) $Valid = 0;
                $condition .= " AND `Valid`={$Valid}";
            }

            // PageSize
            $PageSize = 100;
            if (isset($this->decodedata['PageSize'])) {
                $PageSize = $this->decodedata['PageSize'];
            }
            if($PageSize != 100)
            {
                if(!is_integer($PageSize))
                    $this->error2("The parameter PageSize should be a Interger!", 400);
                if ($PageSize <= 0) {
                    $this->error2("pageSize must be greater than 0!", 400);
                }
            }
            // PageIndex
            $PageIndex = 0;
            if (isset($this->decodedata['PageIndex'])) {
                $PageIndex = $this->decodedata['PageIndex'];
            }
            if($PageIndex != 0)
            {
                if(!is_integer($PageIndex))
                    $this->error2("The parameter PageIndex should be a Interger!", 400);
                if ($PageIndex < 0) {
                    $this->error2("PageIndex must be greater than or equal to 0!", 400);
                }
            }
            $sql0 = "SELECT COUNT(*) as num FROM fence ";
            $sql1 = "SELECT `ID`, `Name`, `Source`, `Rule`, `Valid`, `Type`, `StartTime`, `EndTime`, ";
            $sql1 .= " `PtNum`, `Height` FROM fence";
            if (!empty($condition)) {
                $sql0 .= $condition;
                $sql1 .= $condition;
            }
            $sql1 .= ' LIMIT ' . $PageIndex * $PageSize . ',' . $PageSize;

            $total = Db::connect($this->databaseInfo)->query($sql0);
            $listTotal = Db::connect($this->databaseInfo)->query($sql1);

            // 填充输出的json结构
            // 组合数据
            $dataArray = [];
            $dataArray["total"] = $total[0]['num'];//当前返回设备的个数

            // $data = $list;
            $FenceID_list = [];
            foreach($listTotal as $item)
            {
                if($item['Source'] == '0')  // 动态
                {
                    // 组合ID串，最后统一查询
                    $FenceID_list[] = $item['ID'];
                }
            }

            $listOutline = null;
            if(!empty($FenceID_list))
            {
                // 有动态的Fence
                $strFenceID = join("','", $FenceID_list);
                $sql = "SELECT a.`Fence`, b.`Type`, b.`a`, b.`b`, b.`c` ";
                $sql .= " FROM fence_device a INNER JOIN outline b ON a.`Outline`=b.`ID` ";
                $sql .= " WHERE a.`Fence` IN ('$strFenceID')";
                $listOutline = Db::connect($this->databaseInfo)->query($sql);
            }
            $data = [];
            foreach($listTotal as $itemTotal)
            {
                $SubData = [];
                // 通用部分
                $SubData['ID'] = $itemTotal['ID'];
                $SubData['Name'] = $itemTotal['Name'];
                $SubData['Source'] = $itemTotal['Source']==1?true: false;
                $SubData['Rule'] = $itemTotal['Rule']==1?true: false;
                $SubData['Valid'] = $itemTotal['Valid']==1?true: false;
                $SubData['Type'] = $itemTotal['Type']==1?true: false;
                $SubData['StartTime'] = $itemTotal['StartTime'];
                $SubData['EndTime'] = $itemTotal['EndTime'];
                $SubData['PtNum'] = $itemTotal['PtNum'];
                $SubData['Height'] = $itemTotal['Height'];
                if(!empty($listOutline))
                {
                    // 如果outline有，就组合
                    foreach($listOutline as $itemOutline)
                    {
                        if($itemTotal['ID'] == $itemOutline['Fence'])
                        {
                            unset($itemOutline["Fence"]);
                            $SubData['Outline'] = $itemOutline;
                            break;
                        }
                    }
                }
                $data[] = $SubData;
            }
            $dataArray['result'] = $data;
            $dataArray["PageNum"] = ceil(round((sizeof($listTotal) / $PageSize), 1));
            $this->success2($dataArray);
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    //6.5 获取电子围栏多边形接口
    //http://rhc.test/api/v2/query_fence?ID=ea521e8d-5146-4227-81d0-ab4f99d9cd3a
    public function query_fence()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        }
        else if ($method == 'POST') {
            // 围栏的ID
            $ID = "";
            if (isset($this->decodedata['ID'])) {
                $ID = $this->decodedata['ID'];
            }
            if(!is_string($ID))
            {
                $this->error2("The parameter ID must be a string!", 400);
            }
            
            // 数据库连接
            $connect=mysqli_connect($this->decodedata['ip'],$this->decodedata['username'],$this->databaseInfo['password'],$this->decodedata['scheme']);
            if (mysqli_connect_errno($connect))
            {
                $this->error2('Connect MySQL Fail, ' . mysqli_connect_error(), 400);
            }

            if(empty($ID))
            {
                // 围栏的名称
                $Name = "";
                if (isset($this->decodedata['Name'])) {
                    $Name = $this->decodedata['Name'];
                }
                if(!is_string($Name))
                {
                    $this->error2("The parameter Name must be a string!", 400);
                }
                if(empty($Name))
                {
                    $this->error2("Both ID and Name cannot be empty!", 400);
                }
                // 由Name取出ID，便于后面的统一查询处理
                $sql = "SELECT `ID` FROM fence WHERE `Name` = '{$Name}'";
                $result = mysqli_query($connect, $sql);
                while ($row = mysqli_fetch_assoc($result)) {
                    $ID = $row["ID"];
                }
                if(empty($ID))
                {
                    $this->error2("Have somthing wrong!", 400);
                }
            }
            // 查询
            $sql = "SELECT * FROM fence WHERE `ID`='{$ID}'";
            $listTotal = Db::connect($this->databaseInfo)->query($sql);
            $dataArray = [];
            foreach($listTotal as $itemTotal)
            {
                $listOutline = null;
                if($itemTotal['Source'] == '0') // 是动态fence
                {
                    // 有动态的Fence
                    $sql = "SELECT a.`Fence`, b.`Type`, b.`a`, b.`b`, b.`c` ";
                    $sql .= " FROM fence_device a INNER JOIN outline b ON a.`Outline` = b.`ID` ";
                    $sql .= " WHERE a.`Fence` = '{$ID}'";
                    $listOutline = Db::connect($this->databaseInfo)->query($sql);
                }
                // $dataArray = [];
                // 通用部分
                $dataArray['ID'] = $itemTotal['ID'];
                $dataArray['Name'] = $itemTotal['Name'];
                $dataArray['Source'] = $itemTotal['Source']==1?true: false;
                $dataArray['Rule'] = $itemTotal['Rule']==1?true: false;
                $dataArray['Valid'] = $itemTotal['Valid']==1?true: false;
                $dataArray['Type'] = $itemTotal['Type']==1?true: false;
                $dataArray['StartTime'] = $itemTotal['StartTime'];
                $dataArray['EndTime'] = $itemTotal['EndTime'];
                $dataArray['PtType'] = $itemTotal['PtType'];
                // 判断points
                if(!empty($itemTotal['PtNum']))
                {
                    $Points = unpack("d*", $itemTotal["Points"]);
                    //{"1":121.456,"2":31.5678,"3":121.568,"4":31.9654}
                    $point = [];
                    $i = 0;
                    $lon = 0;
                    foreach ($Points as $v) {
                        if ($i == 0) {
                            $lon = $v;
                        }
                        $i++;
                        if ($i > 1) {
                            $i = 0;
                            $point[] = ["lon"=>$lon, "lat"=>$v];
                        }
                    }
                    $dataArray['point'] = $point;
                }
                $dataArray['Height'] = $itemTotal['Height'];
                // 组合Outline
                if(!empty($listOutline))
                {
                    // 如果outline有，就组合
                    foreach($listOutline as $itemOutline)
                    {
                        if($itemTotal['ID'] == $itemOutline['Fence'])
                        {
                            unset($itemOutline["Fence"]);
                            $dataArray['Outline'] = $itemOutline;
                            break;
                        }
                    }
                }
            }
            $this->success2($dataArray);
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    //6.6 修改电子围栏接口
    //http://rhc.test/api/v2/edit_fence
    public function edit_fence()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        }
        else if ($method == 'POST') {
            // 围栏的ID
            $ID = "";
            if (isset($this->decodedata['ID'])) {
                $ID = $this->decodedata['ID'];
            }
            if(!is_string($ID))
            {
                $this->error2("The parameter ID must be a string!", 400);
            }
            if(empty($ID))
            {
                $this->error2("The parameter ID cannot be null!", 400);
            }
            $sql = "SELECT `Source`,`StartTime`,`EndTime` FROM fence WHERE `ID` = '{$ID}'";
            $result = Db::connect($this->databaseInfo)->query($sql);
            if(count($result) <= 0)
            {
                $this->error2("The parameter ID doesn't exist!", 400);
            }

            $SetCondition = "";
            // Name
            $Name = "";
            if (isset($this->decodedata['Name'])) {
                $Name = $this->decodedata['Name'];
            }
            if(!empty($Name)) {
                if(!is_string($Name)) $this->error2("The parameter Name must be a string!", 400);
                if(!empty($SetCondition)) $SetCondition .= ",";
                $SetCondition .= " `Name`='{$Name}' ";
                // Name的唯一的，如果不唯一就要提示错误
                $sql_sel = "SELECT COUNT(*) AS num FROM fence WHERE `Name`='{$Name}' AND `ID`<>'{$ID}'";
                $total = Db::connect($this->databaseInfo)->query($sql_sel);
                $num = intval($total[0]['num']);
                if($num > 0)
                {
                    $this->error2("The fence name already exists, cannot be updated successfully!", 400);
                }
            }
            // Valid bool类型
            $Valid = -1;
            if (isset($this->decodedata['Valid'])) {
                $Valid = $this->decodedata['Valid'];
            }
            if($Valid !== -1)
            {
                if(!is_bool($Valid))
                    $this->error2("The parameter Valid should be a bool!", 400);
                if($Valid != 1) $Valid = 0;
                if(!empty($SetCondition)) $SetCondition .= ",";
                $SetCondition .= " `Valid`={$Valid} ";
            }
            // Type bool类型
            $Type = -1;
            if (isset($this->decodedata['Type'])) {
                $Rule = $this->decodedata['Type'];
            }
            if($Type !== -1)
            {
                if(!is_bool($Type))
                    $this->error2("The parameter Type should be a bool!", 400);
                if($Type != 1) $Type = 0;
                if(!empty($SetCondition)) $SetCondition .= ",";
                $SetCondition .= " `Type`={$Type} ";
            }
            // Rule bool类型
            $Rule = -1;
            if (isset($this->decodedata['Rule'])) {
                $Rule = $this->decodedata['Rule'];
            }
            if($Rule !== -1)
            {
                if(!is_bool($Rule))
                    $this->error2("The parameter Rule should be a bool!", 400);
                if($Rule != 1) $Rule = 0;
                if(!empty($SetCondition)) $SetCondition .= ",";
                $SetCondition .= " `Rule`={$Rule} ";
            }
            // StartTime
            $StartTime = "";
            if (isset($this->decodedata['StartTime'])) {
                $StartTime = $this->decodedata['StartTime'];
            }
            if(!empty($StartTime))
            {
                if(!is_string($StartTime))
                    $this->error2("The parameter StartTime must be a string!", 400);
                if( strtotime($StartTime) <= 0 or strlen($StartTime) > 9)
                    $this->error2("The parameter StartTime must be 'HH:MM:SS' format!", 400);
            }
            // EndTime
            $EndTime = "";
            if (isset($this->decodedata['EndTime']))
            {
                $EndTime = $this->decodedata['EndTime'];
            }
            if(!empty($EndTime))
            {
                if(!is_string($EndTime))
                    $this->error2("The parameter EndTime must be a string!", 400);
                if( strtotime($EndTime) <= 0 or strlen($EndTime) > 9)
                    $this->error2("The parameter EndTime must be 'HH:MM:SS' format!", 400);
            }
            // 如果EndTime的时间早于StartTime，需要交换
            if(!empty($StartTime) && !empty($EndTime))
            {
                // 2个都要更新，直接对比
                if($EndTime < $StartTime)
                {
                    $this->error2("The EndTime must greater than StartTime!", 400);
                }
                if(!empty($SetCondition)) $SetCondition .= ",";
                $SetCondition .= " `StartTime`='{$StartTime}', `EndTime`='{$EndTime}' ";
            }
            else if(!empty($StartTime) && empty($EndTime))
            {
                // 只更新StartTime，要检查与原来EndTime的大小
                if(!empty($result[0]['EndTime']))
                {
                    if($StartTime > $result[0]['EndTime'])
                    {
                        $this->error2("The StartTime cannot be larger than the old EndTime:". $result[0]['EndTime'], 400);
                    }
                }
                if(!empty($SetCondition)) $SetCondition .= ",";
                $SetCondition .= " `StartTime`='{$StartTime}' ";
            }
            else if(empty($StartTime) && !empty($EndTime))
            {
                // 只更新EndTime，要检查与原来startTime的大小
                if(!empty($result[0]['StartTime']))
                {
                    if($EndTime < $result[0]['StartTime'])
                    {
                        $this->error2("The EndTime cannot be smaller than the old StartTime:". $result[0]['StartTime'], 400);
                    }
                }
                if(!empty($SetCondition)) $SetCondition .= ",";
                $SetCondition .= " `EndTime`='{$EndTime}' ";
            }
            // 最后检查是否是动态Fence，如果是，就更新fence_device表的height
            // Height
            $Height = 0.0;
            if (isset($this->decodedata['Height'])) {
                $Height = $this->decodedata['Height'];
            }
            if($Height !== 0.0)
            {
                if(!is_float($Height) && !is_integer($Height))
                {
                    $this->error2("The Height must be a float!", 400);
                }
                // 判断是不是动态fence
                if($result[0]['Source'] === "0") // 是动态fence
                {
                    #直接更新fence_device表的Height字段
                    $sql_update = "UPDATE fence_device SET `Height` = {$Height} WHERE `Fence` = '{$ID}'";
                    $result = Db::connect($this->databaseInfo)->query($sql_update);
                }
                else
                {
                    if(!empty($SetCondition)) $SetCondition .= ",";
                    $SetCondition .= " `Height`={$Height} ";
                }
            }
            if(!empty($SetCondition))
            {
                // 统一更新Fence表
                $RecordTime = date('Y-m-d H:i:s');
                if(!empty($SetCondition)) $SetCondition .= ",";
                $SetCondition .= " `RecordTime`='{$RecordTime}' ";
                $sql = "UPDATE fence SET {$SetCondition} WHERE `ID` = '{$ID}'";
                $result = Db::connect($this->databaseInfo)->query($sql);
            }
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }

    //7.1 人员定位设备上报定位数据包接口
    //http://rhc.test/api/v2/pos_report
    public function pos_report()
    {
        $method = $this->request->method();
        if ($method == 'GET') {
            $this->error2('Bad Request', 400);
        }
        else if ($method == 'POST') {
            $total = -1;
            if (isset($this->decodedata['total'])) {
                $total = $this->decodedata['total'];
            }
            if($total !== -1)
            {
                if(!is_integer($total))
                    $this->error2("The parameter total should be a Interger!", 400);
                if ($total <= 0) {
                    $this->error2("total must be greater than 0!", 400);
                }
            }
            else
            {
                $this->error2("The parameter total cannot be null!", 400);
            }
            // position
            $position_input = array();
            if (isset($this->decodedata['position'])) {
                $position_input = $this->decodedata['position'];
            }
            if (!is_array($position_input)) {
                $this->error2('The parameter position must be a array!', 400);
            }
            $position_input = array_filter($position_input);
            if(empty($position_input))
            {
                $this->error2("The parameter position cannot be null!", 400);
            }

            // 组合条件
            if($total != count($position_input)) $this->error2("The uploaded position number doesn't match the total number!", 400);
            // 组合成格式：$point = [ [121.456, 31.5678],[121.568,31.9654] ];
            foreach ($position_input as $item)
            {
                if(empty($item['time'])) $this->error2("The parameter time cannot be null!", 400);
                if(!is_integer($item['time'])) $this->error2("The parameter time should be a Interger!", 400);

                if(empty($item['TermID'])) $this->error2("The parameter TermID cannot be null!", 400);
                if(!is_string($item['TermID'])) $this->error2("The parameter TermID must be a string!", 400);

                // 判断TermID是不是存在？
                $sql = "SELECT `ID` FROM device WHERE `TermID`='{$item['TermID']}'";
                $result = Db::connect($this->databaseInfo)->query($sql);
                if(count($result) <= 0)
                {
                    $this->error2("The TermID device doesn't exist!", 400);
                }
                if(empty($item['lon'])) $this->error2("The parameter lon cannot be null!", 400);
                if(!is_float($item['lon'])) $this->error2("The parameter lon must be a float type", 400);
                if(empty($item['lat'])) $this->error2("The parameter lat cannot be null!", 400);
                if(!is_float($item['lat'])) $this->error2("The parameter lat must be a float type", 400);
                if( !$this->isChinaLonLat($item['lon'], $item['lat']) )
                {
                    $this->error2("The LonLat({$item['lon']}, {$item['lat']}) is out of range of china!", 400);
                }

                if(empty($item['alt'])) $this->error2("The parameter alt cannot be null!", 400);
                if( !is_float($item['alt']) && !is_integer($item['alt']) ) $this->error2("The parameter alt must be a float type", 400);

                if(empty($item['status'])) $this->error2("The parameter status cannot be null!", 400);
                if(!is_integer($item['status'])) $this->error2("The parameter status should be a Interger!", 400);
                if($item['status'] < 0 || $item['status'] > 9) $this->error2("The parameter status should be an integer between 1 and 9!", 400);
                $AmapLonLat = $this->beiDouToAMap($item['lon'], $item['lat']);
                // 最后写入position表
                $ID = $this->create_guid();
                $RecordTime = date('Y-m-d H:m:s', $item['time']);
                $sql = "INSERT INTO position (`ID`, `lon`, `lat`, `lon2`, `lat2`, `alt`, `status`, `Device`, `RecordTime`) ";
                $sql .=" VALUES ('{$ID}', {$item['lon']}, {$item['lat']}, {$AmapLonLat[0]}, {$AmapLonLat[1]}, {$item['alt']}, {$item['status']}, '{$result[0]['ID']}', '{$RecordTime}');";
                // 数据库连接
                $connect=mysqli_connect($this->decodedata['ip'],$this->decodedata['username'],$this->databaseInfo['password'],$this->decodedata['scheme']);
                if (mysqli_connect_errno($connect))
                {
                    $this->error2('Connect MySQL Fail, ' . mysqli_connect_error(), 400);
                }
                $InsertResult = mysqli_query($connect, $sql);
                $sql = "UPDATE device SET `Working`=1, `LastTime`='{$RecordTime}' ";
                $sql .= " WHERE `ID`= '{$result[0]['ID']}'";
                $UpdateResult = mysqli_query($connect, $sql);
                mysqli_close($connect);
                // 插入到logue表中
                $url = $this->GetCurUrl();
                $this->InsertLogue($url, json_encode($this->decodedata), 200, "");                
            }
        } else if ($method == 'PUT') {
            $this->error2('Bad Request', 400);
        } else if ($method == 'DELETE') {
            $this->error2('Bad Request', 400);
        }
    }
}